Version 2.11.0-261.0.dev

Merge commit 'b62e715073df0e50e39a55a367b2263e3daf998a' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 04790c5..d215d8f 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -1475,12 +1475,6 @@
   ClassMember get concrete => this;
 
   @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return false;
-  }
-
-  @override
   bool isSameDeclaration(ClassMember other) {
     if (identical(this, other)) return true;
     return other is _SynthesizedFieldClassMember &&
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 2ac1790..58d5882 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -288,11 +288,5 @@
   ClassMember get concrete => this;
 
   @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return false;
-  }
-
-  @override
   String toString() => '$runtimeType($fullName,forSetter=${forSetter})';
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index ef7586e..51255bf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -265,8 +265,6 @@
   ClassMember get abstract;
   ClassMember get concrete;
 
-  bool operator ==(Object other);
-
   void inferType(ClassHierarchyBuilder hierarchy);
   void registerOverrideDependency(Set<ClassMember> overriddenMembers);
 
@@ -2960,32 +2958,6 @@
   void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
     // Do nothing; this is only for declared members.
   }
-
-  @override
-  int get hashCode {
-    int hash = classBuilder.hashCode * 13 +
-        isSetter.hashCode * 17 +
-        isProperty.hashCode * 19 +
-        modifyKernel.hashCode * 23 +
-        name.hashCode * 29;
-    for (ClassMember declaration in declarations) {
-      hash ^= declaration.hashCode;
-    }
-    return hash;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return other is DelayedMember &&
-        classBuilder == other.classBuilder &&
-        isSetter == other.isSetter &&
-        isProperty == other.isProperty &&
-        modifyKernel == other.modifyKernel &&
-        name == other.name &&
-        declarations.length == other.declarations.length &&
-        _equalsList(declarations, other.declarations, declarations.length);
-  }
 }
 
 /// This represents a concrete implementation inherited from a superclass that
@@ -3025,21 +2997,6 @@
         "[${declarations.join(', ')}])";
   }
 
-  @override
-  int get hashCode =>
-      super.hashCode +
-      concreteMember.hashCode * 11 +
-      isInheritableConflict.hashCode * 13;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return super == other &&
-        other is InheritedImplementationInterfaceConflict &&
-        concreteMember == other.concreteMember &&
-        isInheritableConflict == other.isInheritableConflict;
-  }
-
   void _ensureMemberAndCovariance(ClassHierarchyBuilder hierarchy) {
     if (_member == null) {
       if (!classBuilder.isAbstract) {
@@ -3155,24 +3112,6 @@
         "[${declarations.join(', ')}])";
   }
 
-  @override
-  int get hashCode {
-    int hash = super.hashCode;
-    hash ^= isImplicitlyAbstract.hashCode;
-    for (ClassMember declaration in declarations) {
-      hash ^= declaration.hashCode;
-    }
-    return hash;
-  }
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return super == other &&
-        other is InterfaceConflict &&
-        isImplicitlyAbstract == other.isImplicitlyAbstract;
-  }
-
   void _ensureMemberAndCovariance(ClassHierarchyBuilder hierarchy) {
     if (_member != null) {
       return;
@@ -3408,12 +3347,6 @@
   }
 
   @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return super == other && other is AbstractMemberOverridingImplementation;
-  }
-
-  @override
   ClassMember get abstract => abstractMember;
 
   @override
@@ -3580,17 +3513,6 @@
   return declaration is ClassBuilder ? declaration : null;
 }
 
-/// Returns `true` if the first [length] elements of [a] and [b] are the same.
-bool _equalsList<T>(List<T> a, List<T> b, int length) {
-  if (a.length < length || b.length < length) return false;
-  for (int index = 0; index < length; index++) {
-    if (a[index] != b[index]) {
-      return false;
-    }
-  }
-  return true;
-}
-
 Set<ClassMember> toSet(
     ClassBuilder classBuilder, Iterable<ClassMember> members) {
   Set<ClassMember> result = <ClassMember>{};
diff --git a/pkg/front_end/testcases/general/build_issue_2688.dart b/pkg/front_end/testcases/general/build_issue_2688.dart
new file mode 100644
index 0000000..016f457
--- /dev/null
+++ b/pkg/front_end/testcases/general/build_issue_2688.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, 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.
+
+// Regression test for https://github.com/dart-lang/build/issues/2688
+
+mixin M0 {
+  int get property;
+}
+mixin M1 implements M0 {
+  int get property;
+}
+mixin M2 implements M1 {
+  int get property;
+}
+mixin M3 implements M2 {
+  int get property;
+}
+mixin M4 implements M3 {
+  int get property;
+}
+mixin M5 implements M4 {
+  int get property;
+}
+mixin M6 implements M5 {
+  int get property;
+}
+mixin M7 implements M6 {
+  int get property;
+}
+mixin M8 implements M7 {
+  int get property;
+}
+mixin M9 implements M8 {
+  int get property;
+}
+mixin M10 implements M9 {
+  int get property;
+}
+mixin M11 implements M10 {
+  int get property;
+}
+mixin M12 implements M11 {
+  int get property;
+}
+mixin M13 implements M12 {
+  int get property;
+}
+mixin M14 implements M13 {
+  int get property;
+}
+mixin M15 implements M14 {
+  int get property;
+}
+mixin M16 implements M15 {
+  int get property;
+}
+mixin M17 implements M16 {
+  int get property;
+}
+mixin M18 implements M17 {
+  int get property;
+}
+mixin M19 implements M18 {
+  int get property;
+}
+mixin M20 implements M19 {
+  int get property;
+}
+mixin M21 implements M20 {
+  int get property;
+}
+mixin M22 implements M21 {
+  int get property;
+}
+mixin M23 implements M22 {
+  int get property;
+}
+mixin M24 implements M23 {
+  int get property;
+}
+mixin M25 implements M24 {
+  int get property;
+}
+mixin M26 implements M25 {
+  int get property;
+}
+mixin M27 implements M26 {
+  int get property;
+}
+
+abstract class Super {
+  int get property;
+}
+
+class Class extends Super
+    with
+        M0,
+        M1,
+        M2,
+        M3,
+        M4,
+        M5,
+        M6,
+        M7,
+        M8,
+        M9,
+        M10,
+        M11,
+        M12,
+        M13,
+        M14,
+        M15,
+        M16,
+        M17,
+        M18,
+        M19,
+        M20,
+        M21,
+        M22,
+        M23,
+        M24,
+        M25,
+        M26,
+        M27 {
+  int get property => 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/build_issue_2688.dart.outline.expect b/pkg/front_end/testcases/general/build_issue_2688.dart.outline.expect
new file mode 100644
index 0000000..43701f7
--- /dev/null
+++ b/pkg/front_end/testcases/general/build_issue_2688.dart.outline.expect
@@ -0,0 +1,531 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super*
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0 = self::Super with self::M0 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0*
+    : super self::Super::•()
+    ;
+}
+abstract class _Class&Super&M0&M1 = self::_Class&Super&M0 with self::M1 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1*
+    : super self::_Class&Super&M0::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2 = self::_Class&Super&M0&M1 with self::M2 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2*
+    : super self::_Class&Super&M0&M1::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3 = self::_Class&Super&M0&M1&M2 with self::M3 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3*
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 = self::_Class&Super&M0&M1&M2&M3 with self::M4 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4*
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 = self::_Class&Super&M0&M1&M2&M3&M4 with self::M5 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5*
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 = self::_Class&Super&M0&M1&M2&M3&M4&M5 with self::M6 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 with self::M7 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 with self::M8 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 with self::M9 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 with self::M10 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 with self::M11 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 with self::M12 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 with self::M13 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 with self::M14 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 with self::M15 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 with self::M16 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 with self::M17 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 with self::M18 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 with self::M19 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 with self::M20 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 with self::M21 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 with self::M22 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 with self::M23 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 with self::M24 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 with self::M25 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 with self::M26 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 with self::M27 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class*
+    ;
+  get property() → core::int*
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/build_issue_2688.dart.strong.expect b/pkg/front_end/testcases/general/build_issue_2688.dart.strong.expect
new file mode 100644
index 0000000..eee4f5a
--- /dev/null
+++ b/pkg/front_end/testcases/general/build_issue_2688.dart.strong.expect
@@ -0,0 +1,532 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super*
+    : super core::Object::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0 = self::Super with self::M0 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0*
+    : super self::Super::•()
+    ;
+}
+abstract class _Class&Super&M0&M1 = self::_Class&Super&M0 with self::M1 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1*
+    : super self::_Class&Super&M0::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2 = self::_Class&Super&M0&M1 with self::M2 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2*
+    : super self::_Class&Super&M0&M1::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3 = self::_Class&Super&M0&M1&M2 with self::M3 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3*
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 = self::_Class&Super&M0&M1&M2&M3 with self::M4 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4*
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 = self::_Class&Super&M0&M1&M2&M3&M4 with self::M5 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5*
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 = self::_Class&Super&M0&M1&M2&M3&M4&M5 with self::M6 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 with self::M7 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 with self::M8 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 with self::M9 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 with self::M10 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 with self::M11 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 with self::M12 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 with self::M13 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 with self::M14 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 with self::M15 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 with self::M16 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 with self::M17 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 with self::M18 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 with self::M19 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 with self::M20 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 with self::M21 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 with self::M22 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 with self::M23 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 with self::M24 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 with self::M25 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 with self::M26 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 with self::M27 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27::•()
+    ;
+  get property() → core::int*
+    return 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/build_issue_2688.dart.strong.transformed.expect b/pkg/front_end/testcases/general/build_issue_2688.dart.strong.transformed.expect
new file mode 100644
index 0000000..bce18c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/build_issue_2688.dart.strong.transformed.expect
@@ -0,0 +1,840 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super*
+    : super core::Object::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0 extends self::Super implements self::M0 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0*
+    : super self::Super::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1 extends self::_Class&Super&M0 implements self::M1 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1*
+    : super self::_Class&Super&M0::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2 extends self::_Class&Super&M0&M1 implements self::M2 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2*
+    : super self::_Class&Super&M0&M1::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3 extends self::_Class&Super&M0&M1&M2 implements self::M3 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3*
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 extends self::_Class&Super&M0&M1&M2&M3 implements self::M4 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4*
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 extends self::_Class&Super&M0&M1&M2&M3&M4 implements self::M5 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5*
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 extends self::_Class&Super&M0&M1&M2&M3&M4&M5 implements self::M6 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 implements self::M7 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 implements self::M8 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 implements self::M9 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 implements self::M10 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 implements self::M11 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 implements self::M12 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 implements self::M13 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 implements self::M14 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 implements self::M15 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 implements self::M16 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 implements self::M17 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 implements self::M18 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 implements self::M19 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 implements self::M20 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 implements self::M21 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 implements self::M22 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 implements self::M23 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 implements self::M24 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 implements self::M25 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 implements self::M26 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 implements self::M27 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+  abstract get property() → core::int*;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class*
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27::•()
+    ;
+  get property() → core::int*
+    return 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/build_issue_2688.dart.textual_outline.expect b/pkg/front_end/testcases/general/build_issue_2688.dart.textual_outline.expect
new file mode 100644
index 0000000..ed52349
--- /dev/null
+++ b/pkg/front_end/testcases/general/build_issue_2688.dart.textual_outline.expect
@@ -0,0 +1,123 @@
+mixin M0 {
+  int get property;
+}
+mixin M1 implements M0 {
+  int get property;
+}
+mixin M2 implements M1 {
+  int get property;
+}
+mixin M3 implements M2 {
+  int get property;
+}
+mixin M4 implements M3 {
+  int get property;
+}
+mixin M5 implements M4 {
+  int get property;
+}
+mixin M6 implements M5 {
+  int get property;
+}
+mixin M7 implements M6 {
+  int get property;
+}
+mixin M8 implements M7 {
+  int get property;
+}
+mixin M9 implements M8 {
+  int get property;
+}
+mixin M10 implements M9 {
+  int get property;
+}
+mixin M11 implements M10 {
+  int get property;
+}
+mixin M12 implements M11 {
+  int get property;
+}
+mixin M13 implements M12 {
+  int get property;
+}
+mixin M14 implements M13 {
+  int get property;
+}
+mixin M15 implements M14 {
+  int get property;
+}
+mixin M16 implements M15 {
+  int get property;
+}
+mixin M17 implements M16 {
+  int get property;
+}
+mixin M18 implements M17 {
+  int get property;
+}
+mixin M19 implements M18 {
+  int get property;
+}
+mixin M20 implements M19 {
+  int get property;
+}
+mixin M21 implements M20 {
+  int get property;
+}
+mixin M22 implements M21 {
+  int get property;
+}
+mixin M23 implements M22 {
+  int get property;
+}
+mixin M24 implements M23 {
+  int get property;
+}
+mixin M25 implements M24 {
+  int get property;
+}
+mixin M26 implements M25 {
+  int get property;
+}
+mixin M27 implements M26 {
+  int get property;
+}
+
+abstract class Super {
+  int get property;
+}
+
+class Class extends Super
+    with
+        M0,
+        M1,
+        M2,
+        M3,
+        M4,
+        M5,
+        M6,
+        M7,
+        M8,
+        M9,
+        M10,
+        M11,
+        M12,
+        M13,
+        M14,
+        M15,
+        M16,
+        M17,
+        M18,
+        M19,
+        M20,
+        M21,
+        M22,
+        M23,
+        M24,
+        M25,
+        M26,
+        M27 {
+  int get property => 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/build_issue_2688.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/build_issue_2688.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2ec562
--- /dev/null
+++ b/pkg/front_end/testcases/general/build_issue_2688.dart.textual_outline_modelled.expect
@@ -0,0 +1,122 @@
+abstract class Super {
+  int get property;
+}
+
+class Class extends Super
+    with
+        M0,
+        M1,
+        M2,
+        M3,
+        M4,
+        M5,
+        M6,
+        M7,
+        M8,
+        M9,
+        M10,
+        M11,
+        M12,
+        M13,
+        M14,
+        M15,
+        M16,
+        M17,
+        M18,
+        M19,
+        M20,
+        M21,
+        M22,
+        M23,
+        M24,
+        M25,
+        M26,
+        M27 {
+  int get property => 0;
+}
+
+main() {}
+mixin M0 {
+  int get property;
+}
+mixin M1 implements M0 {
+  int get property;
+}
+mixin M10 implements M9 {
+  int get property;
+}
+mixin M11 implements M10 {
+  int get property;
+}
+mixin M12 implements M11 {
+  int get property;
+}
+mixin M13 implements M12 {
+  int get property;
+}
+mixin M14 implements M13 {
+  int get property;
+}
+mixin M15 implements M14 {
+  int get property;
+}
+mixin M16 implements M15 {
+  int get property;
+}
+mixin M17 implements M16 {
+  int get property;
+}
+mixin M18 implements M17 {
+  int get property;
+}
+mixin M19 implements M18 {
+  int get property;
+}
+mixin M2 implements M1 {
+  int get property;
+}
+mixin M20 implements M19 {
+  int get property;
+}
+mixin M21 implements M20 {
+  int get property;
+}
+mixin M22 implements M21 {
+  int get property;
+}
+mixin M23 implements M22 {
+  int get property;
+}
+mixin M24 implements M23 {
+  int get property;
+}
+mixin M25 implements M24 {
+  int get property;
+}
+mixin M26 implements M25 {
+  int get property;
+}
+mixin M27 implements M26 {
+  int get property;
+}
+mixin M3 implements M2 {
+  int get property;
+}
+mixin M4 implements M3 {
+  int get property;
+}
+mixin M5 implements M4 {
+  int get property;
+}
+mixin M6 implements M5 {
+  int get property;
+}
+mixin M7 implements M6 {
+  int get property;
+}
+mixin M8 implements M7 {
+  int get property;
+}
+mixin M9 implements M8 {
+  int get property;
+}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart b/pkg/front_end/testcases/nnbd/build_issue_2688.dart
new file mode 100644
index 0000000..016f457
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2020, 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.
+
+// Regression test for https://github.com/dart-lang/build/issues/2688
+
+mixin M0 {
+  int get property;
+}
+mixin M1 implements M0 {
+  int get property;
+}
+mixin M2 implements M1 {
+  int get property;
+}
+mixin M3 implements M2 {
+  int get property;
+}
+mixin M4 implements M3 {
+  int get property;
+}
+mixin M5 implements M4 {
+  int get property;
+}
+mixin M6 implements M5 {
+  int get property;
+}
+mixin M7 implements M6 {
+  int get property;
+}
+mixin M8 implements M7 {
+  int get property;
+}
+mixin M9 implements M8 {
+  int get property;
+}
+mixin M10 implements M9 {
+  int get property;
+}
+mixin M11 implements M10 {
+  int get property;
+}
+mixin M12 implements M11 {
+  int get property;
+}
+mixin M13 implements M12 {
+  int get property;
+}
+mixin M14 implements M13 {
+  int get property;
+}
+mixin M15 implements M14 {
+  int get property;
+}
+mixin M16 implements M15 {
+  int get property;
+}
+mixin M17 implements M16 {
+  int get property;
+}
+mixin M18 implements M17 {
+  int get property;
+}
+mixin M19 implements M18 {
+  int get property;
+}
+mixin M20 implements M19 {
+  int get property;
+}
+mixin M21 implements M20 {
+  int get property;
+}
+mixin M22 implements M21 {
+  int get property;
+}
+mixin M23 implements M22 {
+  int get property;
+}
+mixin M24 implements M23 {
+  int get property;
+}
+mixin M25 implements M24 {
+  int get property;
+}
+mixin M26 implements M25 {
+  int get property;
+}
+mixin M27 implements M26 {
+  int get property;
+}
+
+abstract class Super {
+  int get property;
+}
+
+class Class extends Super
+    with
+        M0,
+        M1,
+        M2,
+        M3,
+        M4,
+        M5,
+        M6,
+        M7,
+        M8,
+        M9,
+        M10,
+        M11,
+        M12,
+        M13,
+        M14,
+        M15,
+        M16,
+        M17,
+        M18,
+        M19,
+        M20,
+        M21,
+        M22,
+        M23,
+        M24,
+        M25,
+        M26,
+        M27 {
+  int get property => 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.outline.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.outline.expect
new file mode 100644
index 0000000..8b55238
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.outline.expect
@@ -0,0 +1,241 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0 = self::Super with self::M0 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0
+    : super self::Super::•()
+    ;
+}
+abstract class _Class&Super&M0&M1 = self::_Class&Super&M0 with self::M1 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1
+    : super self::_Class&Super&M0::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2 = self::_Class&Super&M0&M1 with self::M2 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2
+    : super self::_Class&Super&M0&M1::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3 = self::_Class&Super&M0&M1&M2 with self::M3 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 = self::_Class&Super&M0&M1&M2&M3 with self::M4 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 = self::_Class&Super&M0&M1&M2&M3&M4 with self::M5 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 = self::_Class&Super&M0&M1&M2&M3&M4&M5 with self::M6 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 with self::M7 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 with self::M8 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 with self::M9 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 with self::M10 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 with self::M11 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 with self::M12 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 with self::M13 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 with self::M14 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 with self::M15 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 with self::M16 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 with self::M17 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 with self::M18 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 with self::M19 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 with self::M20 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 with self::M21 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 with self::M22 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 with self::M23 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 with self::M24 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 with self::M25 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 with self::M26 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 with self::M27 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class
+    ;
+  get property() → core::int
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.strong.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.strong.expect
new file mode 100644
index 0000000..974275d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.strong.expect
@@ -0,0 +1,242 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0 = self::Super with self::M0 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0
+    : super self::Super::•()
+    ;
+}
+abstract class _Class&Super&M0&M1 = self::_Class&Super&M0 with self::M1 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1
+    : super self::_Class&Super&M0::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2 = self::_Class&Super&M0&M1 with self::M2 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2
+    : super self::_Class&Super&M0&M1::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3 = self::_Class&Super&M0&M1&M2 with self::M3 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 = self::_Class&Super&M0&M1&M2&M3 with self::M4 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 = self::_Class&Super&M0&M1&M2&M3&M4 with self::M5 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 = self::_Class&Super&M0&M1&M2&M3&M4&M5 with self::M6 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 with self::M7 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 with self::M8 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 with self::M9 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 with self::M10 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 with self::M11 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 with self::M12 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 with self::M13 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 with self::M14 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 with self::M15 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 with self::M16 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 with self::M17 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 with self::M18 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 with self::M19 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 with self::M20 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 with self::M21 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 with self::M22 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 with self::M23 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 with self::M24 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 with self::M25 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 with self::M26 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 with self::M27 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27::•()
+    ;
+  get property() → core::int
+    return 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.strong.transformed.expect
new file mode 100644
index 0000000..a9961fa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.strong.transformed.expect
@@ -0,0 +1,270 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0 extends self::Super implements self::M0 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0
+    : super self::Super::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1 extends self::_Class&Super&M0 implements self::M1 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1
+    : super self::_Class&Super&M0::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2 extends self::_Class&Super&M0&M1 implements self::M2 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2
+    : super self::_Class&Super&M0&M1::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3 extends self::_Class&Super&M0&M1&M2 implements self::M3 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 extends self::_Class&Super&M0&M1&M2&M3 implements self::M4 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 extends self::_Class&Super&M0&M1&M2&M3&M4 implements self::M5 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 extends self::_Class&Super&M0&M1&M2&M3&M4&M5 implements self::M6 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 implements self::M7 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 implements self::M8 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 implements self::M9 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 implements self::M10 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 implements self::M11 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 implements self::M12 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 implements self::M13 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 implements self::M14 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 implements self::M15 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 implements self::M16 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 implements self::M17 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 implements self::M18 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 implements self::M19 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 implements self::M20 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 implements self::M21 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 implements self::M22 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 implements self::M23 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 implements self::M24 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 implements self::M25 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 implements self::M26 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 implements self::M27 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+  abstract get property() → core::int;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27::•()
+    ;
+  get property() → core::int
+    return 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.textual_outline.expect
new file mode 100644
index 0000000..ed52349
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.textual_outline.expect
@@ -0,0 +1,123 @@
+mixin M0 {
+  int get property;
+}
+mixin M1 implements M0 {
+  int get property;
+}
+mixin M2 implements M1 {
+  int get property;
+}
+mixin M3 implements M2 {
+  int get property;
+}
+mixin M4 implements M3 {
+  int get property;
+}
+mixin M5 implements M4 {
+  int get property;
+}
+mixin M6 implements M5 {
+  int get property;
+}
+mixin M7 implements M6 {
+  int get property;
+}
+mixin M8 implements M7 {
+  int get property;
+}
+mixin M9 implements M8 {
+  int get property;
+}
+mixin M10 implements M9 {
+  int get property;
+}
+mixin M11 implements M10 {
+  int get property;
+}
+mixin M12 implements M11 {
+  int get property;
+}
+mixin M13 implements M12 {
+  int get property;
+}
+mixin M14 implements M13 {
+  int get property;
+}
+mixin M15 implements M14 {
+  int get property;
+}
+mixin M16 implements M15 {
+  int get property;
+}
+mixin M17 implements M16 {
+  int get property;
+}
+mixin M18 implements M17 {
+  int get property;
+}
+mixin M19 implements M18 {
+  int get property;
+}
+mixin M20 implements M19 {
+  int get property;
+}
+mixin M21 implements M20 {
+  int get property;
+}
+mixin M22 implements M21 {
+  int get property;
+}
+mixin M23 implements M22 {
+  int get property;
+}
+mixin M24 implements M23 {
+  int get property;
+}
+mixin M25 implements M24 {
+  int get property;
+}
+mixin M26 implements M25 {
+  int get property;
+}
+mixin M27 implements M26 {
+  int get property;
+}
+
+abstract class Super {
+  int get property;
+}
+
+class Class extends Super
+    with
+        M0,
+        M1,
+        M2,
+        M3,
+        M4,
+        M5,
+        M6,
+        M7,
+        M8,
+        M9,
+        M10,
+        M11,
+        M12,
+        M13,
+        M14,
+        M15,
+        M16,
+        M17,
+        M18,
+        M19,
+        M20,
+        M21,
+        M22,
+        M23,
+        M24,
+        M25,
+        M26,
+        M27 {
+  int get property => 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2ec562
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.textual_outline_modelled.expect
@@ -0,0 +1,122 @@
+abstract class Super {
+  int get property;
+}
+
+class Class extends Super
+    with
+        M0,
+        M1,
+        M2,
+        M3,
+        M4,
+        M5,
+        M6,
+        M7,
+        M8,
+        M9,
+        M10,
+        M11,
+        M12,
+        M13,
+        M14,
+        M15,
+        M16,
+        M17,
+        M18,
+        M19,
+        M20,
+        M21,
+        M22,
+        M23,
+        M24,
+        M25,
+        M26,
+        M27 {
+  int get property => 0;
+}
+
+main() {}
+mixin M0 {
+  int get property;
+}
+mixin M1 implements M0 {
+  int get property;
+}
+mixin M10 implements M9 {
+  int get property;
+}
+mixin M11 implements M10 {
+  int get property;
+}
+mixin M12 implements M11 {
+  int get property;
+}
+mixin M13 implements M12 {
+  int get property;
+}
+mixin M14 implements M13 {
+  int get property;
+}
+mixin M15 implements M14 {
+  int get property;
+}
+mixin M16 implements M15 {
+  int get property;
+}
+mixin M17 implements M16 {
+  int get property;
+}
+mixin M18 implements M17 {
+  int get property;
+}
+mixin M19 implements M18 {
+  int get property;
+}
+mixin M2 implements M1 {
+  int get property;
+}
+mixin M20 implements M19 {
+  int get property;
+}
+mixin M21 implements M20 {
+  int get property;
+}
+mixin M22 implements M21 {
+  int get property;
+}
+mixin M23 implements M22 {
+  int get property;
+}
+mixin M24 implements M23 {
+  int get property;
+}
+mixin M25 implements M24 {
+  int get property;
+}
+mixin M26 implements M25 {
+  int get property;
+}
+mixin M27 implements M26 {
+  int get property;
+}
+mixin M3 implements M2 {
+  int get property;
+}
+mixin M4 implements M3 {
+  int get property;
+}
+mixin M5 implements M4 {
+  int get property;
+}
+mixin M6 implements M5 {
+  int get property;
+}
+mixin M7 implements M6 {
+  int get property;
+}
+mixin M8 implements M7 {
+  int get property;
+}
+mixin M9 implements M8 {
+  int get property;
+}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.weak.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.weak.expect
new file mode 100644
index 0000000..974275d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.weak.expect
@@ -0,0 +1,242 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0 = self::Super with self::M0 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0
+    : super self::Super::•()
+    ;
+}
+abstract class _Class&Super&M0&M1 = self::_Class&Super&M0 with self::M1 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1
+    : super self::_Class&Super&M0::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2 = self::_Class&Super&M0&M1 with self::M2 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2
+    : super self::_Class&Super&M0&M1::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3 = self::_Class&Super&M0&M1&M2 with self::M3 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 = self::_Class&Super&M0&M1&M2&M3 with self::M4 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 = self::_Class&Super&M0&M1&M2&M3&M4 with self::M5 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 = self::_Class&Super&M0&M1&M2&M3&M4&M5 with self::M6 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 with self::M7 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 with self::M8 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 with self::M9 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 with self::M10 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 with self::M11 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 with self::M12 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 with self::M13 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 with self::M14 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 with self::M15 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 with self::M16 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 with self::M17 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 with self::M18 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 with self::M19 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 with self::M20 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 with self::M21 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 with self::M22 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 with self::M23 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 with self::M24 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 with self::M25 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 with self::M26 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 = self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 with self::M27 /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27::•()
+    ;
+  get property() → core::int
+    return 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/build_issue_2688.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.weak.transformed.expect
new file mode 100644
index 0000000..a9961fa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/build_issue_2688.dart.weak.transformed.expect
@@ -0,0 +1,270 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class M0 extends core::Object /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M1 extends core::Object implements self::M0 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M2 extends core::Object implements self::M1 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M3 extends core::Object implements self::M2 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M4 extends core::Object implements self::M3 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M5 extends core::Object implements self::M4 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M6 extends core::Object implements self::M5 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M7 extends core::Object implements self::M6 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M8 extends core::Object implements self::M7 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M9 extends core::Object implements self::M8 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M10 extends core::Object implements self::M9 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M11 extends core::Object implements self::M10 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M12 extends core::Object implements self::M11 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M13 extends core::Object implements self::M12 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M14 extends core::Object implements self::M13 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M15 extends core::Object implements self::M14 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M16 extends core::Object implements self::M15 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M17 extends core::Object implements self::M16 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M18 extends core::Object implements self::M17 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M19 extends core::Object implements self::M18 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M20 extends core::Object implements self::M19 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M21 extends core::Object implements self::M20 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M22 extends core::Object implements self::M21 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M23 extends core::Object implements self::M22 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M24 extends core::Object implements self::M23 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M25 extends core::Object implements self::M24 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M26 extends core::Object implements self::M25 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class M27 extends core::Object implements self::M26 /*isMixinDeclaration*/  {
+  abstract get property() → core::int;
+}
+abstract class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0 extends self::Super implements self::M0 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0
+    : super self::Super::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1 extends self::_Class&Super&M0 implements self::M1 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1
+    : super self::_Class&Super&M0::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2 extends self::_Class&Super&M0&M1 implements self::M2 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2
+    : super self::_Class&Super&M0&M1::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3 extends self::_Class&Super&M0&M1&M2 implements self::M3 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3
+    : super self::_Class&Super&M0&M1&M2::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4 extends self::_Class&Super&M0&M1&M2&M3 implements self::M4 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4
+    : super self::_Class&Super&M0&M1&M2&M3::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5 extends self::_Class&Super&M0&M1&M2&M3&M4 implements self::M5 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5
+    : super self::_Class&Super&M0&M1&M2&M3&M4::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6 extends self::_Class&Super&M0&M1&M2&M3&M4&M5 implements self::M6 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6 implements self::M7 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7 implements self::M8 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8 implements self::M9 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9 implements self::M10 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10 implements self::M11 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11 implements self::M12 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12 implements self::M13 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13 implements self::M14 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14 implements self::M15 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15 implements self::M16 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16 implements self::M17 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17 implements self::M18 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18 implements self::M19 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19 implements self::M20 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20 implements self::M21 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21 implements self::M22 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22 implements self::M23 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23 implements self::M24 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24 implements self::M25 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25 implements self::M26 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25::•()
+    ;
+  abstract get property() → core::int;
+}
+abstract class _Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26 implements self::M27 /*isAnonymousMixin,isEliminatedMixin*/  {
+  synthetic constructor •() → self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26::•()
+    ;
+  abstract get property() → core::int;
+}
+class Class extends self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27 {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Super&M0&M1&M2&M3&M4&M5&M6&M7&M8&M9&M10&M11&M12&M13&M14&M15&M16&M17&M18&M19&M20&M21&M22&M23&M24&M25&M26&M27::•()
+    ;
+  get property() → core::int
+    return 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index bad218c..d36d3be 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1535,14 +1535,13 @@
 
   Args<Type> argumentTypes(Member member) => _summaries[member]?.argumentTypes;
 
+  Type argumentType(Member member, VariableDeclaration memberParam) {
+    return _summaries[member]?.argumentType(member, memberParam);
+  }
+
   List<VariableDeclaration> uncheckedParameters(Member member) =>
       _summaries[member]?.uncheckedParameters;
 
-  // The set of optional and named parameters to this procedure which
-  // are passed at all call-sites.
-  Set<String> alwaysPassedOptionalParameters(Member member) =>
-      _summaries[member]?.alwaysPassedOptionalParameters() ?? const {};
-
   bool isTearOffTaken(Member member) => _tearOffTaken.contains(member);
 
   /// Returns true if this member is called on a receiver with static type
@@ -1565,6 +1564,12 @@
       _methodsAndSettersCalledDynamically.contains(member) ||
       _calledViaInterfaceSelector.contains(member);
 
+  /// Update the summary parameters to reflect a signature change with moved
+  /// and/or removed parameters.
+  void adjustFunctionParameters(Member member) {
+    _summaries[member]?.adjustFunctionParameters(member);
+  }
+
   /// ---- Implementation of [CallHandler] interface. ----
 
   @override
@@ -1648,4 +1653,9 @@
   void recordMemberCalledViaThis(Member target) {
     _calledViaThis.add(target);
   }
+
+  @override
+  void recordTearOff(Procedure target) {
+    _tearOffTaken.add(target);
+  }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index cdd0d0a..f935383 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -187,20 +187,15 @@
   final List<T> values;
   final List<String> names;
 
-  // Whether it is not known which optional arguments are passed or not.
-  final bool unknownArity;
-
   int _hashCode;
 
-  Args(this.values,
-      {this.names = const <String>[], this.unknownArity = false}) {
+  Args(this.values, {this.names = const <String>[]}) {
     assert(isSorted(names));
   }
 
   Args.withReceiver(Args<T> args, T receiver)
       : values = new List.from(args.values),
-        names = args.names,
-        unknownArity = args.unknownArity {
+        names = args.names {
     values[0] = receiver;
   }
 
@@ -220,7 +215,6 @@
     for (var n in names) {
       hash = (((hash * 31) & kHashMask) + n.hashCode) & kHashMask;
     }
-    if (unknownArity) hash ^= -1;
     return hash;
   }
 
@@ -240,7 +234,7 @@
           return false;
         }
       }
-      return unknownArity == other.unknownArity;
+      return true;
     }
     return false;
   }
@@ -263,11 +257,7 @@
       buf.write(': ');
       buf.write(values[positionalCount + i]);
     }
-    if (unknownArity) {
-      buf.write(", <unknown arity>)");
-    } else {
-      buf.write(")");
-    }
+    buf.write(")");
     return buf.toString();
   }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 0d00188..ba8a56d 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -32,6 +32,9 @@
 
   /// Record the fact that given member is called from this.
   void recordMemberCalledViaThis(Member target);
+
+  /// Record the fact that given method is torn off.
+  void recordTearOff(Procedure target) {}
 }
 
 class PragmaEntryPointsVisitor extends RecursiveVisitor {
diff --git a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
new file mode 100644
index 0000000..e1a947c
--- /dev/null
+++ b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
@@ -0,0 +1,523 @@
+// Copyright (c) 2020, 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.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/external_name.dart';
+import 'package:kernel/type_environment.dart';
+
+import 'analysis.dart';
+import 'table_selector_assigner.dart';
+import 'types.dart';
+import 'utils.dart';
+import '../../metadata/procedure_attributes.dart';
+
+/// Transform parameters from optional to required when they are always passed,
+/// and remove parameters which are never passed or never used.
+///
+/// Signatures of static functions are considered on their own. Instance methods
+/// are grouped by table selector ID and thus can cover several implementations.
+///
+/// Definitions:
+/// - A parameter is used if it is mentioned in the body (or, for constructors,
+///   an initializer) of any implementation.
+/// - A parameter can be eliminated if either:
+///   1. it is not used; or
+///   2. it is never passed and is not written to in any implementation.
+/// - A function is eligible if it is not external and is guaranteed to not be
+///   called with an unknown call signature.
+///
+/// All eligible signatures are transformed such that they contain, in order:
+/// 1. All used positional parameters that are always passed, as required
+///    positional parameters.
+/// 2. All used named parameters that are always passed, as required positional
+///    parameters, alphabetically by name.
+/// 3. All used positional parameters that are not always passed and can't be
+///    eliminated, as positional parameters, each one required iff it was
+///    originally required.
+/// 4. All used named parameters that are not always passed and can't be
+///    eliminated, as named parameters in alphabetical order.
+class SignatureShaker {
+  final TypeFlowAnalysis typeFlowAnalysis;
+  final TableSelectorAssigner tableSelectorAssigner;
+
+  final Map<Member, _ProcedureInfo> _memberInfo = {};
+  final Map<int, _ProcedureInfo> _selectorInfo = {};
+
+  SignatureShaker(this.typeFlowAnalysis, this.tableSelectorAssigner);
+
+  _ProcedureInfo _infoForMember(Member member) {
+    if (!(member is Procedure &&
+            (member.kind == ProcedureKind.Method ||
+                member.kind == ProcedureKind.Factory) ||
+        member is Constructor)) {
+      return null;
+    }
+    if (member.isInstanceMember) {
+      final selectorId = tableSelectorAssigner.methodOrSetterSelectorId(member);
+      assert(selectorId != ProcedureAttributesMetadata.kInvalidSelectorId);
+      return _selectorInfo.putIfAbsent(selectorId, () => _ProcedureInfo());
+    } else {
+      return _memberInfo.putIfAbsent(member, () => _ProcedureInfo());
+    }
+  }
+
+  void transformComponent(Component component) {
+    _Collect(this).visitComponent(component);
+    _Transform(this).visitComponent(component);
+  }
+}
+
+class _ProcedureInfo {
+  final List<_ParameterInfo> positional = [];
+  final Map<String, _ParameterInfo> named = {};
+  int callCount = 0;
+  bool eligible = true;
+
+  _ParameterInfo ensurePositional(int i) {
+    if (positional.length <= i) {
+      assert(positional.length == i);
+      positional.add(_ParameterInfo(this, i));
+    }
+    return positional[i];
+  }
+
+  _ParameterInfo ensureNamed(String name) {
+    return named.putIfAbsent(name, () => _ParameterInfo(this, null));
+  }
+
+  bool transformNeeded(FunctionNode function) {
+    return positional.any((param) =>
+            param.canBeEliminated ||
+            (param.isAlwaysPassed &&
+                param.index >= function.requiredParameterCount)) ||
+        named.values
+            .any((param) => param.canBeEliminated || param.isAlwaysPassed);
+  }
+}
+
+class _ParameterInfo {
+  final _ProcedureInfo info;
+  final int index;
+
+  int passCount = 0;
+  bool isRead = false;
+  bool isWritten = false;
+
+  _ParameterInfo(this.info, this.index);
+
+  bool get isNamed => index == null;
+
+  bool get isUsed => isRead || isWritten;
+
+  bool get isAlwaysPassed => passCount == info.callCount;
+
+  bool get isNeverPassed => passCount == 0;
+
+  bool get canBeEliminated => !isUsed || isNeverPassed && !isWritten;
+
+  void observeImplicitChecks(
+      Member member, VariableDeclaration param, SignatureShaker shaker) {
+    if (param.isCovariant || param.isGenericCovariantImpl) {
+      // Covariant parameters have implicit type checks, which count as reads.
+      isRead = true;
+    } else if (param.type.nullability == Nullability.nonNullable) {
+      // When run in weak mode with null assertions enabled, parameters with
+      // non-nullable types have implicit null checks, which count as reads.
+      Type type = shaker.typeFlowAnalysis.argumentType(member, param);
+      if (type == null || type is NullableType) {
+        // TFA can't guarantee that the value isn't null. Preserve check.
+        isRead = true;
+      }
+    }
+  }
+}
+
+class _Collect extends RecursiveVisitor<void> {
+  final SignatureShaker shaker;
+
+  final Map<VariableDeclaration, _ParameterInfo> localParameters = {};
+
+  _Collect(this.shaker);
+
+  void enterFunction(Member member) {
+    final _ProcedureInfo info = shaker._infoForMember(member);
+    if (info == null) return;
+
+    localParameters.clear();
+    final FunctionNode fun = member.function;
+    for (int i = 0; i < fun.positionalParameters.length; i++) {
+      final VariableDeclaration param = fun.positionalParameters[i];
+      localParameters[param] = info.ensurePositional(i)
+        ..observeImplicitChecks(member, param, shaker);
+    }
+    for (VariableDeclaration param in fun.namedParameters) {
+      localParameters[param] = info.ensureNamed(param.name)
+        ..observeImplicitChecks(member, param, shaker);
+    }
+
+    if (shaker.typeFlowAnalysis.isCalledDynamically(member) ||
+        shaker.typeFlowAnalysis.isTearOffTaken(member) ||
+        shaker.typeFlowAnalysis.nativeCodeOracle
+            .isMemberReferencedFromNativeCode(member) ||
+        getExternalName(member) != null) {
+      info.eligible = false;
+    }
+  }
+
+  @override
+  void visitProcedure(Procedure node) {
+    enterFunction(node);
+    super.visitProcedure(node);
+  }
+
+  @override
+  void visitConstructor(Constructor node) {
+    enterFunction(node);
+    super.visitConstructor(node);
+  }
+
+  @override
+  void visitVariableGet(VariableGet node) {
+    localParameters[node.variable]?.isRead = true;
+    super.visitVariableGet(node);
+  }
+
+  @override
+  void visitVariableSet(VariableSet node) {
+    localParameters[node.variable]?.isWritten = true;
+    super.visitVariableSet(node);
+  }
+
+  void collectCall(Member member, Arguments args) {
+    final _ProcedureInfo info = shaker._infoForMember(member);
+    if (info == null) return;
+
+    for (int i = 0; i < args.positional.length; i++) {
+      info.ensurePositional(i).passCount++;
+    }
+    for (NamedExpression named in args.named) {
+      info.ensureNamed(named.name).passCount++;
+    }
+    info.callCount++;
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    collectCall(node.interfaceTarget, node.arguments);
+    super.visitMethodInvocation(node);
+  }
+
+  @override
+  void visitSuperMethodInvocation(SuperMethodInvocation node) {
+    collectCall(node.interfaceTarget, node.arguments);
+    super.visitSuperMethodInvocation(node);
+  }
+
+  @override
+  void visitStaticInvocation(StaticInvocation node) {
+    collectCall(node.target, node.arguments);
+    super.visitStaticInvocation(node);
+  }
+
+  @override
+  void visitConstructorInvocation(ConstructorInvocation node) {
+    collectCall(node.target, node.arguments);
+    super.visitConstructorInvocation(node);
+  }
+
+  @override
+  void visitRedirectingInitializer(RedirectingInitializer node) {
+    collectCall(node.target, node.arguments);
+    super.visitRedirectingInitializer(node);
+  }
+
+  @override
+  void visitSuperInitializer(SuperInitializer node) {
+    collectCall(node.target, node.arguments);
+    super.visitSuperInitializer(node);
+  }
+}
+
+class _Transform extends RecursiveVisitor<void> {
+  final SignatureShaker shaker;
+
+  StaticTypeContext typeContext;
+  final Set<VariableDeclaration> eliminatedParams = {};
+  final List<LocalInitializer> addedInitializers = [];
+
+  _Transform(this.shaker);
+
+  void transformMemberSignature(Member member) {
+    typeContext =
+        StaticTypeContext(member, shaker.typeFlowAnalysis.environment);
+    eliminatedParams.clear();
+
+    final _ProcedureInfo info = shaker._infoForMember(member);
+    if (info == null || !info.eligible || info.callCount == 0) return;
+
+    final FunctionNode function = member.function;
+
+    if (!info.transformNeeded(function)) return;
+
+    final List<VariableDeclaration> positional = [];
+    final List<VariableDeclaration> named = [];
+    // 1. All used positional parameters that are always passed, as required
+    //    positional parameters.
+    for (int i = 0; i < function.positionalParameters.length; i++) {
+      final _ParameterInfo param = info.positional[i];
+      if (!param.isAlwaysPassed) break;
+      if (param.isUsed) {
+        final VariableDeclaration variable = function.positionalParameters[i];
+        positional.add(variable);
+        variable.initializer = null;
+      }
+    }
+    // 2. All used named parameters that are always passed, as required
+    //    positional parameters, alphabetically by name.
+    final List<VariableDeclaration> sortedNamed = function.namedParameters
+        .toList()
+          ..sort((var1, var2) => var1.name.compareTo(var2.name));
+    for (VariableDeclaration variable in sortedNamed) {
+      final _ParameterInfo param = info.named[variable.name];
+      if (param.isUsed && param.isAlwaysPassed) {
+        variable.initializer = null;
+        variable.isRequired = false;
+        positional.add(variable);
+      }
+    }
+    int requiredParameterCount = positional.length;
+    // 3. All used positional parameters that are not always passed and can't be
+    //    eliminated, as positional parameters, each one required iff it was
+    //    originally required.
+    for (int i = 0; i < function.positionalParameters.length; i++) {
+      final _ParameterInfo param = info.positional[i];
+      if (param.isUsed) {
+        final VariableDeclaration variable = function.positionalParameters[i];
+        if (param.canBeEliminated) {
+          assert(variable.initializer == null ||
+              variable.initializer is ConstantExpression);
+          eliminatedParams.add(variable);
+        } else if (!param.isAlwaysPassed) {
+          positional.add(variable);
+          if (i < function.requiredParameterCount) {
+            // The parameter is required, but it is not always passed. This is
+            // possible if the method is overridden by a method which makes the
+            // parameter optional.
+            assert(variable.initializer == null);
+            requiredParameterCount++;
+          }
+        }
+      }
+    }
+    // 4. All used named parameters that are not always passed and can't be
+    //    eliminated, as named parameters in alphabetical order.
+    for (VariableDeclaration variable in sortedNamed) {
+      final _ParameterInfo param = info.named[variable.name];
+      if (param.isUsed) {
+        if (param.canBeEliminated) {
+          assert(variable.initializer == null ||
+              variable.initializer is ConstantExpression);
+          eliminatedParams.add(variable);
+        } else if (!param.isAlwaysPassed) {
+          named.add(variable);
+        }
+      }
+    }
+
+    assert(requiredParameterCount <= positional.length);
+    function.requiredParameterCount = requiredParameterCount;
+    function.positionalParameters = positional;
+    function.namedParameters = named;
+
+    shaker.typeFlowAnalysis.adjustFunctionParameters(member);
+  }
+
+  @override
+  void visitVariableGet(VariableGet node) {
+    if (eliminatedParams.contains(node.variable)) {
+      final ConstantExpression initializer = node.variable.initializer;
+      node.replaceWith(
+          ConstantExpression(initializer?.constant ?? NullConstant()));
+    }
+  }
+
+  @override
+  void visitConstructor(Constructor node) {
+    transformMemberSignature(node);
+    super.visitConstructor(node);
+    if (addedInitializers.isNotEmpty) {
+      // Insert hoisted constructor arguments before this/super initializer.
+      assert(node.initializers.last is RedirectingInitializer ||
+          node.initializers.last is SuperInitializer);
+      node.initializers
+          .insertAll(node.initializers.length - 1, addedInitializers.reversed);
+      addedInitializers.clear();
+    }
+  }
+
+  @override
+  void visitProcedure(Procedure node) {
+    transformMemberSignature(node);
+    super.visitProcedure(node);
+  }
+
+  static void forEachArgumentRev(Arguments args, _ProcedureInfo info,
+      void Function(Expression, _ParameterInfo) fun) {
+    for (int i = args.named.length - 1; i >= 0; i--) {
+      final NamedExpression namedExp = args.named[i];
+      fun(namedExp.value, info.named[namedExp.name]);
+    }
+    for (int i = args.positional.length - 1; i >= 0; i--) {
+      fun(args.positional[i], info.positional[i]);
+    }
+  }
+
+  void transformCall(
+      Member target, TreeNode call, Expression receiver, Arguments args) {
+    final _ProcedureInfo info = shaker._infoForMember(target);
+    if (info == null || !info.eligible) return;
+
+    bool transformNeeded = false;
+    bool hoistingNeeded = false;
+    forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
+      assert(!param.isNeverPassed);
+      if (!param.isUsed || param.isNamed && param.isAlwaysPassed) {
+        transformNeeded = true;
+        if (mayHaveSideEffects(arg)) {
+          hoistingNeeded = true;
+        }
+      }
+    });
+
+    if (!transformNeeded) return;
+
+    Map<Expression, VariableDeclaration> hoisted = {};
+    if (hoistingNeeded) {
+      if (call is Initializer) {
+        final Constructor constructor = call.parent;
+        forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
+          if (mayHaveOrSeeSideEffects(arg)) {
+            VariableDeclaration argVar = VariableDeclaration(null,
+                initializer: arg,
+                type: arg.getStaticType(typeContext),
+                isFinal: true);
+            addedInitializers
+                .add(LocalInitializer(argVar)..parent = constructor);
+            hoisted[arg] = argVar;
+          }
+        });
+      } else {
+        final TreeNode parent = call.parent;
+        Expression current = call;
+        forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
+          if (mayHaveOrSeeSideEffects(arg)) {
+            VariableDeclaration argVar = VariableDeclaration(null,
+                initializer: arg,
+                type: arg.getStaticType(typeContext),
+                isFinal: true);
+            current = Let(argVar, current);
+            hoisted[arg] = argVar;
+          }
+        });
+        if (receiver != null && mayHaveOrSeeSideEffects(receiver)) {
+          assert(receiver.parent == call);
+          final VariableDeclaration receiverVar = VariableDeclaration(null,
+              initializer: receiver,
+              type: receiver.getStaticType(typeContext),
+              isFinal: true);
+          current = Let(receiverVar, current);
+          call.replaceChild(receiver, VariableGet(receiverVar));
+        }
+
+        parent.replaceChild(call, current);
+      }
+    }
+
+    Expression getMaybeHoistedArg(Expression arg) {
+      final variable = hoisted[arg];
+      if (variable == null) return arg;
+      return VariableGet(variable);
+    }
+
+    final List<Expression> positional = [];
+    final List<NamedExpression> named = [];
+    // 1. All used positional parameters that are always passed, as required
+    //    positional parameters.
+    for (int i = 0; i < args.positional.length; i++) {
+      final _ParameterInfo param = info.positional[i];
+      final Expression arg = args.positional[i];
+      if (param.isUsed && param.isAlwaysPassed) {
+        positional.add(getMaybeHoistedArg(arg));
+      }
+    }
+    // 2. All used named parameters that are always passed, as required
+    //    positional parameters, alphabetically by name.
+    final List<NamedExpression> sortedNamed = args.named.toList()
+      ..sort((var1, var2) => var1.name.compareTo(var2.name));
+    for (NamedExpression arg in sortedNamed) {
+      final _ParameterInfo param = info.named[arg.name];
+      if (param.isUsed && param.isAlwaysPassed) {
+        positional.add(getMaybeHoistedArg(arg.value));
+      }
+    }
+    // 3. All used positional parameters that are not always passed and can't be
+    //    eliminated, as positional parameters, each one required iff it was
+    //    originally required.
+    for (int i = 0; i < args.positional.length; i++) {
+      final _ParameterInfo param = info.positional[i];
+      final Expression arg = args.positional[i];
+      if (param.isUsed && !param.isAlwaysPassed) {
+        positional.add(getMaybeHoistedArg(arg));
+      }
+    }
+    // 4. All used named parameters that are not always passed and can't be
+    //    eliminated, as named parameters in alphabetical order.
+    //    (Arguments are kept in original order.)
+    for (NamedExpression arg in args.named) {
+      final _ParameterInfo param = info.named[arg.name];
+      if (param.isUsed && !param.isAlwaysPassed) {
+        arg.value = getMaybeHoistedArg(arg.value)..parent = arg;
+        named.add(arg);
+      }
+    }
+
+    args.replaceWith(Arguments(positional, named: named, types: args.types));
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    super.visitMethodInvocation(node);
+    transformCall(node.interfaceTarget, node, node.receiver, node.arguments);
+  }
+
+  @override
+  void visitSuperMethodInvocation(SuperMethodInvocation node) {
+    super.visitSuperMethodInvocation(node);
+    transformCall(node.interfaceTarget, node, null, node.arguments);
+  }
+
+  @override
+  void visitStaticInvocation(StaticInvocation node) {
+    super.visitStaticInvocation(node);
+    transformCall(node.target, node, null, node.arguments);
+  }
+
+  @override
+  void visitConstructorInvocation(ConstructorInvocation node) {
+    super.visitConstructorInvocation(node);
+    transformCall(node.target, node, null, node.arguments);
+  }
+
+  @override
+  void visitRedirectingInitializer(RedirectingInitializer node) {
+    super.visitRedirectingInitializer(node);
+    transformCall(node.target, node, null, node.arguments);
+  }
+
+  @override
+  void visitSuperInitializer(SuperInitializer node) {
+    super.visitSuperInitializer(node);
+    transformCall(node.target, node, null, node.arguments);
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index ef97516..d529e68 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -74,9 +74,6 @@
   Type defaultValue;
   Type _argumentType = const EmptyType();
 
-  // Whether this parameter is passed at all call-sites.
-  bool isAlwaysPassed = true;
-
   Parameter(this.name, this.staticTypeForNarrowing);
 
   @override
@@ -108,7 +105,6 @@
   }
 
   Type _observeNotPassed(TypeHierarchy typeHierarchy) {
-    isAlwaysPassed = false;
     final Type argType = defaultValue.specialize(typeHierarchy);
     _observeArgumentType(argType, typeHierarchy);
     return argType;
@@ -590,9 +586,9 @@
 /// Summary is a linear sequence of statements representing a type flow in
 /// one member, function or initializer.
 class Summary {
-  final int parameterCount;
-  final int positionalParameterCount;
-  final int requiredParameterCount;
+  int parameterCount;
+  int positionalParameterCount;
+  int requiredParameterCount;
 
   List<Statement> _statements = <Statement>[];
   TypeExpr result = null;
@@ -643,12 +639,6 @@
 
     List<Type> types = new List<Type>(_statements.length);
 
-    if (arguments.unknownArity) {
-      for (int i = 0; i < parameterCount; ++i) {
-        (_statements[i] as Parameter).isAlwaysPassed = false;
-      }
-    }
-
     for (int i = 0; i < positionalArgCount; i++) {
       final Parameter param = _statements[i] as Parameter;
       if (args[i] is RuntimeType) {
@@ -726,6 +716,26 @@
     return new Args<Type>(argTypes, names: argNames);
   }
 
+  Type argumentType(Member member, VariableDeclaration memberParam) {
+    final int firstParamIndex =
+        numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
+    final positional = member.function.positionalParameters;
+    for (int i = 0; i < positional.length; i++) {
+      if (positional[i] == memberParam) {
+        final Parameter param = _statements[firstParamIndex + i] as Parameter;
+        assert(param.name == memberParam.name);
+        return param.argumentType;
+      }
+    }
+    for (int i = positionalParameterCount; i < parameterCount; i++) {
+      final Parameter param = _statements[i] as Parameter;
+      if (param.name == memberParam.name) {
+        return param.argumentType;
+      }
+    }
+    throw "Could not find argument type of parameter ${memberParam.name}";
+  }
+
   List<VariableDeclaration> get uncheckedParameters {
     final params = List<VariableDeclaration>();
     for (Statement statement in _statements) {
@@ -738,14 +748,29 @@
     return params;
   }
 
-  Set<String> alwaysPassedOptionalParameters() {
-    final params = Set<String>();
-    for (int i = requiredParameterCount; i < parameterCount; ++i) {
-      final Parameter p = _statements[i] as Parameter;
-      if (p.isAlwaysPassed) {
-        params.add(p.name);
-      }
+  /// Update the summary parameters to reflect a signature change with moved
+  /// and/or removed parameters.
+  void adjustFunctionParameters(Member member) {
+    // Just keep the parameters part of the summary, assuming that the rest is
+    // not used in later phases. The index values in the statements will be
+    // incorrect, but those are assumed to be not used either.
+    final int implicit =
+        (hasReceiverArg(member) ? 1 : 0) + numTypeParams(member);
+    final Map<String, Parameter> paramsByName = {};
+    for (int i = implicit; i < parameterCount; i++) {
+      final Parameter param = statements[i];
+      paramsByName[param.name] = param;
     }
-    return params;
+    FunctionNode function = member.function;
+    statements.length = implicit;
+    for (VariableDeclaration param in function.positionalParameters) {
+      statements.add(paramsByName[param.name]);
+    }
+    positionalParameterCount = statements.length;
+    for (VariableDeclaration param in function.namedParameters) {
+      statements.add(paramsByName[param.name]);
+    }
+    parameterCount = statements.length;
+    requiredParameterCount = implicit + function.requiredParameterCount;
   }
 }
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index b545936..64170aa 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -847,7 +847,7 @@
         break;
     }
 
-    return new Args<Type>(args, names: names, unknownArity: true);
+    return new Args<Type>(args, names: names);
   }
 
   TypeExpr _visit(TreeNode node) => node.accept(this);
@@ -2423,6 +2423,7 @@
     final Procedure procedure = constant.procedure;
     summaryCollector._entryPointsListener
         .addRawCall(new DirectSelector(procedure));
+    summaryCollector._entryPointsListener.recordTearOff(procedure);
     return _getStaticType(constant);
   }
 
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index cf64db8..53f5219 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -13,10 +13,10 @@
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/library_index.dart' show LibraryIndex;
 import 'package:kernel/type_environment.dart';
-import 'package:kernel/external_name.dart';
 
 import 'analysis.dart';
 import 'calls.dart';
+import 'signature_shaking.dart';
 import 'protobuf_handler.dart' show ProtobufHandler;
 import 'summary.dart';
 import 'table_selector_assigner.dart';
@@ -86,7 +86,6 @@
   final transformsStopWatch = new Stopwatch()..start();
 
   final treeShaker = new TreeShaker(component, typeFlowAnalysis,
-      treeShakeSignatures: treeShakeSignatures,
       treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
   treeShaker.transformComponent(component);
 
@@ -96,6 +95,12 @@
 
   final tableSelectorAssigner = new TableSelectorAssigner(component);
 
+  if (treeShakeSignatures) {
+    final signatureShaker =
+        new SignatureShaker(typeFlowAnalysis, tableSelectorAssigner);
+    signatureShaker.transformComponent(component);
+  }
+
   final unboxingInfo = new UnboxingInfoManager(typeFlowAnalysis)
     ..analyzeComponent(component, typeFlowAnalysis, tableSelectorAssigner);
 
@@ -103,8 +108,6 @@
           tableSelectorAssigner, unboxingInfo)
       .visitComponent(component);
 
-  treeShaker.finalizeSignatures();
-
   transformsStopWatch.stop();
 
   statPrint("TF analysis took ${analysisStopWatch.elapsedMilliseconds}ms");
@@ -510,17 +513,14 @@
   _TreeShakerConstantVisitor constantVisitor;
   _TreeShakerPass1 _pass1;
   _TreeShakerPass2 _pass2;
-  _SignatureShaker _signatureShaker;
 
   TreeShaker(Component component, this.typeFlowAnalysis,
-      {bool treeShakeSignatures: true, this.treeShakeWriteOnlyFields: true}) {
+      {this.treeShakeWriteOnlyFields: true}) {
     fieldMorpher = new FieldMorpher(this);
     typeVisitor = new _TreeShakerTypeVisitor(this);
     constantVisitor = new _TreeShakerConstantVisitor(this, typeVisitor);
     _pass1 = new _TreeShakerPass1(this);
     _pass2 = new _TreeShakerPass2(this);
-    _signatureShaker = new _SignatureShaker(this.typeFlowAnalysis,
-        treeShakeSignatures: treeShakeSignatures);
   }
 
   transformComponent(Component component) {
@@ -528,10 +528,6 @@
     _pass2.transform(component);
   }
 
-  finalizeSignatures() {
-    _signatureShaker.transform();
-  }
-
   bool isClassReferencedFromNativeCode(Class c) =>
       typeFlowAnalysis.nativeCodeOracle.isClassReferencedFromNativeCode(c);
   bool isClassUsed(Class c) => _usedClasses.contains(c);
@@ -795,7 +791,6 @@
   final TreeShaker shaker;
   final FieldMorpher fieldMorpher;
   final TypeEnvironment environment;
-  final List<Initializer> additionalInitializers = [];
   Procedure _unsafeCast;
 
   StaticTypeContext _staticTypeContext;
@@ -923,20 +918,6 @@
   }
 
   @override
-  Constructor visitConstructor(Constructor node) {
-    additionalInitializers.clear();
-    node = defaultMember(node);
-    if (additionalInitializers.isNotEmpty) {
-      assert(node.initializers.last is SuperInitializer ||
-          node.initializers.last is RedirectingInitializer);
-      additionalInitializers.forEach((i) => i.parent = node);
-      node.initializers
-          .insertAll(node.initializers.length - 1, additionalInitializers);
-    }
-    return node;
-  }
-
-  @override
   TreeNode defaultMember(Member node) {
     currentMember = node;
     if (shaker.isMemberBodyReachable(node)) {
@@ -1078,83 +1059,6 @@
     }
   }
 
-  Expression _fixArgumentEvaluationOrder(
-      Expression invocation, Arguments args) {
-    if (args.named.isEmpty) return invocation;
-
-    Expression outer = invocation;
-    for (int i = args.named.length - 1; i >= 0; --i) {
-      final arg = args.named[i];
-      final variable = VariableDeclaration(null,
-          initializer: arg.value,
-          type: arg.value.getStaticType(staticTypeContext));
-      arg.value = VariableGet(variable)..parent = arg;
-      outer = Let(variable, outer);
-    }
-    for (int i = args.positional.length - 1; i >= 0; --i) {
-      final variable = VariableDeclaration(null,
-          initializer: args.positional[i],
-          type: args.positional[i].getStaticType(staticTypeContext));
-      args.positional[i] = VariableGet(variable)..parent = args;
-      outer = Let(variable, outer);
-    }
-    return outer;
-  }
-
-  void _fixArgumentEvaluationOrderInInitializer(Arguments args) {
-    if (args.named.isEmpty) return;
-
-    for (int i = 0; i < args.positional.length; ++i) {
-      final variable =
-          VariableDeclaration(null, initializer: args.positional[i]);
-      args.positional[i] = VariableGet(variable)..parent = args;
-      additionalInitializers.add(LocalInitializer(variable));
-    }
-    for (int i = 0; i < args.named.length; ++i) {
-      final variable =
-          VariableDeclaration(null, initializer: args.named[i].value);
-      args.named[i].value = VariableGet(variable)..parent = args.named[i];
-      additionalInitializers.add(LocalInitializer(variable));
-    }
-  }
-
-  void _rewriteArguments(Arguments args, Member member) {
-    final alwaysPassedParams =
-        shaker.typeFlowAnalysis.alwaysPassedOptionalParameters(member);
-    final func = member.function;
-    final positional = args.positional.toList();
-    final newPositional = args.positional;
-    newPositional.removeRange(
-        func.requiredParameterCount, newPositional.length);
-
-    for (int i = func.requiredParameterCount; i < positional.length; ++i) {
-      if (alwaysPassedParams.contains(func.positionalParameters[i].name)) {
-        newPositional.add(positional[i]);
-      }
-    }
-
-    final newNamed = <NamedExpression>[];
-    final namedPositionals = <NamedExpression>[];
-    for (int i = 0; i < args.named.length; i++) {
-      final arg = args.named[i];
-      if (alwaysPassedParams.contains(arg.name)) {
-        namedPositionals.add(arg);
-      } else {
-        newNamed.add(arg);
-      }
-    }
-    args.named = newNamed;
-    namedPositionals.sort((x, y) => x.name.compareTo(y.name));
-    newPositional
-        .addAll(namedPositionals.map((expr) => expr.value..parent = args));
-
-    for (int i = func.requiredParameterCount; i < positional.length; ++i) {
-      if (!alwaysPassedParams.contains(func.positionalParameters[i].name)) {
-        newPositional.add(positional[i]);
-      }
-    }
-  }
-
   @override
   TreeNode visitStaticInvocation(StaticInvocation node) {
     node.transformChildren(this);
@@ -1166,10 +1070,7 @@
     assert(shaker.isMemberBodyReachable(target),
         "Member body is not reachable: $target");
 
-    if (!shaker._signatureShaker.isShakingSignature(target)) return node;
-    final result = _fixArgumentEvaluationOrder(node, node.arguments);
-    _rewriteArguments(node.arguments, target);
-    return result;
+    return node;
   }
 
   @override
@@ -1220,10 +1121,7 @@
         assert(node.isConst);
         shaker.addUsedMember(node.target);
       }
-      if (!shaker._signatureShaker.isShakingSignature(node.target)) return node;
-      final result = _fixArgumentEvaluationOrder(node, node.arguments);
-      _rewriteArguments(node.arguments, node.target);
-      return result;
+      return node;
     }
   }
 
@@ -1235,9 +1133,6 @@
     } else {
       assert(shaker.isMemberBodyReachable(node.target),
           "Target should be reachable: ${node.target}");
-      if (!shaker._signatureShaker.isShakingSignature(node.target)) return node;
-      _fixArgumentEvaluationOrderInInitializer(node.arguments);
-      _rewriteArguments(node.arguments, node.target);
       return node;
     }
   }
@@ -1249,9 +1144,6 @@
       return _makeUnreachableInitializer(_flattenArguments(node.arguments));
     } else {
       // Can't assert that node.target is used due to partial mixin resolution.
-      if (!shaker._signatureShaker.isShakingSignature(node.target)) return node;
-      _fixArgumentEvaluationOrderInInitializer(node.arguments);
-      _rewriteArguments(node.arguments, node.target);
       return node;
     }
   }
@@ -1408,34 +1300,6 @@
       node.enclosingClass.isEnum;
 
   @override
-  Member visitProcedure(Procedure proc) {
-    proc = defaultMember(proc);
-    if (proc == null || !shaker._signatureShaker.isShakingSignature(proc)) {
-      return proc;
-    }
-    final optionals =
-        shaker.typeFlowAnalysis.alwaysPassedOptionalParameters(proc);
-    if (optionals.isNotEmpty) {
-      shaker._signatureShaker.defer(proc);
-    }
-    return proc;
-  }
-
-  @override
-  Member visitConstructor(Constructor ctor) {
-    ctor = defaultMember(ctor);
-    if (ctor == null || !shaker._signatureShaker.isShakingSignature(ctor)) {
-      return ctor;
-    }
-    final optionals =
-        shaker.typeFlowAnalysis.alwaysPassedOptionalParameters(ctor);
-    if (optionals.isNotEmpty) {
-      shaker._signatureShaker.defer(ctor);
-    }
-    return ctor;
-  }
-
-  @override
   Member defaultMember(Member node) {
     if (!shaker.isMemberUsed(node) && !_preserveSpecialMember(node)) {
       // Ensure that kernel file writer will not be able to
@@ -1514,86 +1378,6 @@
   }
 }
 
-// Transform signatures of functions to convert optional named and
-// positional parameters to required parameters if we know that all call sites
-// will pass them.
-//
-// Because the AnnotateKernel pass expects signatures to match up with the
-// corresponding summaries, we enqueue the functions which need to be transformed
-// during the _TreeShakerPass1 and delay the actual transformation until after
-// AnnotateKernel has run.
-class _SignatureShaker {
-  final TypeFlowAnalysis analysis;
-  final List<Member> deferred = [];
-  final bool treeShakeSignatures;
-  _SignatureShaker(this.analysis, {this.treeShakeSignatures});
-
-  bool isShakingSignature(Member member) {
-    if (!treeShakeSignatures) return false;
-    if (member is Procedure && member.isStatic || member is Constructor) {
-      if (getExternalName(member) != null) {
-        // This member has a native implementation which we cannot rewrite
-        // to accomodate the new signature.
-        return false;
-      }
-    } else {
-      return false;
-    }
-    final alwaysPassedParams = analysis.alwaysPassedOptionalParameters(member);
-    return alwaysPassedParams.isNotEmpty;
-  }
-
-  void defer(Member m) {
-    assert(isShakingSignature(m));
-    deferred.add(m);
-  }
-
-  void transform() => deferred.forEach(_update);
-
-  void _update(Member member) {
-    final alwaysPassedOptionals =
-        analysis.alwaysPassedOptionalParameters(member);
-    assert(alwaysPassedOptionals.isNotEmpty);
-
-    final func = member.function;
-    final newPositional =
-        func.positionalParameters.sublist(0, func.requiredParameterCount);
-    final optionalPositional =
-        func.positionalParameters.sublist(func.requiredParameterCount);
-
-    for (final param in optionalPositional) {
-      if (alwaysPassedOptionals.contains(param.name)) {
-        newPositional.add(param..initializer = null);
-      }
-    }
-
-    final namedPositionals = <VariableDeclaration>[];
-    final namedParameters = <VariableDeclaration>[];
-    for (final param in func.namedParameters) {
-      if (alwaysPassedOptionals.contains(param.name)) {
-        // Make sure to clear the isRequired flag in case it was set.
-        param.isRequired = false;
-        namedPositionals.add(param..initializer = null);
-      } else {
-        namedParameters.add(param);
-      }
-    }
-    namedPositionals.sort((x, y) => x.name.compareTo(y.name));
-    newPositional.addAll(namedPositionals);
-
-    func.requiredParameterCount = newPositional.length;
-
-    for (final param in optionalPositional) {
-      if (!alwaysPassedOptionals.contains(param.name)) {
-        newPositional.add(param);
-      }
-    }
-
-    func.positionalParameters = newPositional;
-    func.namedParameters = namedParameters;
-  }
-}
-
 class _TreeShakerConstantVisitor extends ConstantVisitor<Null> {
   final TreeShaker shaker;
   final _TreeShakerTypeVisitor typeVisitor;
@@ -1671,26 +1455,3 @@
     constant.type.accept(typeVisitor);
   }
 }
-
-bool mayHaveSideEffects(Expression node) {
-  if (node is BasicLiteral ||
-      node is ConstantExpression ||
-      node is ThisExpression) {
-    return false;
-  }
-  if (node is VariableGet && !node.variable.isLate) {
-    return false;
-  }
-  if (node is StaticGet) {
-    final target = node.target;
-    if (target is Field && !target.isLate) {
-      final initializer = target.initializer;
-      if (initializer == null ||
-          initializer is BasicLiteral ||
-          initializer is ConstantExpression) {
-        return false;
-      }
-    }
-  }
-  return true;
-}
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index ca2e212..2502904 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -329,3 +329,45 @@
 
 bool isComparisonWithNull(MethodInvocation node) =>
     getArgumentOfComparisonWithNull(node) != null;
+
+bool mayHaveSideEffects(Expression node) {
+  // Keep this function in sync with mayHaveOrSeeSideEffects:
+  // If new false cases are added here, add the corresponding visibility cases
+  // to mayHaveOrSeeSideEffects.
+  if (node is BasicLiteral ||
+      node is ConstantExpression ||
+      node is ThisExpression) {
+    return false;
+  }
+  if (node is VariableGet && !node.variable.isLate) {
+    return false;
+  }
+  if (node is StaticGet) {
+    final target = node.target;
+    if (target is Field && !target.isLate) {
+      final initializer = target.initializer;
+      if (initializer == null ||
+          initializer is BasicLiteral ||
+          initializer is ConstantExpression) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool mayHaveOrSeeSideEffects(Expression node) {
+  if (mayHaveSideEffects(node)) {
+    return true;
+  }
+  if (node is VariableGet && !node.variable.isFinal) {
+    return true;
+  }
+  if (node is StaticGet) {
+    final target = node.target;
+    if (target is Field && !target.isFinal) {
+      return true;
+    }
+  }
+  return false;
+}
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 969556a..1e63109 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -56,6 +56,9 @@
 
   @override
   void recordMemberCalledViaThis(Member target) {}
+
+  @override
+  void recordTearOff(Procedure target) {}
 }
 
 class PrintSummaries extends RecursiveVisitor<Null> {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
index a67cf66..28378be 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -28,7 +28,7 @@
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5]  @#C8
   method instanceMethod() → void {}
 }
-[@vm.unboxing-info.metadata=(b)->i]static method foo([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (core::List<core::int*>*) →* void a) → core::int* {
+[@vm.unboxing-info.metadata=()->i]static method foo() → core::int* {
   @#C9 core::int* x = 2;
   return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+] [@vm.inferred-type.metadata=int (skip check)] x.{core::num::+}(2);
 }
@@ -36,5 +36,5 @@
 static method main(core::List<core::String*>* args) → dynamic {
   self::A::staticMethod();
   [@vm.direct-call.metadata=#lib::B.instanceMethod] [@vm.inferred-type.metadata=!? (skip check)] new self::B::•().{self::B::instanceMethod}();
-  self::foo(null);
+  self::foo();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
index 76d2329..8d122c1 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/const_prop.dart.expect
@@ -20,11 +20,11 @@
 [@vm.unboxing-info.metadata=(i)->b]static method test0([@vm.inferred-type.metadata=dart.core::_Smi (value: 40)] core::int* arg) → void {
   core::print(arg);
 }
-static method test1([[@vm.inferred-type.metadata=dart.core::_Smi (value: 42)] core::int* arg = #C1]) → void {
-  core::print(arg);
+static method test1() → void {
+  core::print(#C1);
 }
-static method test2({[@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* arg = #C2}) → void {
-  core::print(arg);
+static method test2() → void {
+  core::print(#C2);
 }
 [@vm.unboxing-info.metadata=()->d]static get getD() → dynamic
   return 100.0;
@@ -45,9 +45,9 @@
 }
 static method getList() → dynamic
   return #C6;
-static method testList([@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2, 3])] dynamic arg1, [[@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[4, 5])] dynamic arg2 = #C9]) → void {
+static method testList([@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2, 3])] dynamic arg1) → void {
   core::print(arg1);
-  core::print(arg2);
+  core::print(#C9);
 }
 static method main() → dynamic {
   self::test0(40);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
index 4c6d0e1..79e29be 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -58,7 +58,7 @@
   self::callerA1(new self::B::•());
   self::callerA1(new self::C::•());
   self::callerA2(new self::B::•());
-  let self::C* #t1 = new self::C::•() in self::callerA3(#t1);
+  let final self::C* #t1 = new self::C::•() in self::callerA3(#t1);
   self::callerA4([@vm.inferred-type.metadata=#lib::D?] self::dd);
   self::dd = new self::D::•();
   self::callerE1("abc");
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart
index 3fb1a95..f253547 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart
@@ -4,14 +4,31 @@
 
 import 'dart:async';
 
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
+
 class A {}
 
 class B extends A {}
 
-void foo1_a1(x) {}
-void foo1_a2(x) {}
-void foo1_a3(x) {}
-void foo1_a4(x) {}
+void foo1_a1(x) {
+  use(x);
+}
+
+void foo1_a2(x) {
+  use(x);
+}
+
+void foo1_a3(x) {
+  use(x);
+}
+
+void foo1_a4(x) {
+  use(x);
+}
 
 void foo1(Future<A> a1, A a2, FutureOr<A> a3, FutureOr<A> a4) {
   foo1_a1(a1);
@@ -20,10 +37,21 @@
   foo1_a4(a4);
 }
 
-void foo2_a1(x) {}
-void foo2_a2(x) {}
-void foo2_a3(x) {}
-void foo2_a4(x) {}
+void foo2_a1(x) {
+  use(x);
+}
+
+void foo2_a2(x) {
+  use(x);
+}
+
+void foo2_a3(x) {
+  use(x);
+}
+
+void foo2_a4(x) {
+  use(x);
+}
 
 void foo2(Future<A> a1, A a2, FutureOr<A> a3, FutureOr<A> a4) {
   foo2_a1(a1);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index be9cfcc..32c6fb4 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -15,21 +15,41 @@
     : super self::A::•()
     ;
 }
+static field dynamic usedObject;
 [@vm.inferred-type.metadata=dart.core::Null? (value: null)]static field core::Function* unknown;
-static method foo1_a1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {}
-static method foo1_a2([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {}
-static method foo1_a3([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {}
-static method foo1_a4([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {}
+static method use(dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
+static method foo1_a1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {
+  self::use(x);
+}
+static method foo1_a2([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {
+  self::use(x);
+}
+static method foo1_a3([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] dynamic x) → void {
+  self::use(x);
+}
+static method foo1_a4([@vm.inferred-type.metadata=#lib::B] dynamic x) → void {
+  self::use(x);
+}
 static method foo1([@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B] self::A* a2, [@vm.inferred-type.metadata=dart.async::_Future<#lib::B*>] FutureOr<self::A*>* a3, [@vm.inferred-type.metadata=#lib::B] FutureOr<self::A*>* a4) → void {
   self::foo1_a1(a1);
   self::foo1_a2(a2);
   self::foo1_a3(a3);
   self::foo1_a4(a4);
 }
-static method foo2_a1([@vm.inferred-type.metadata=dart.async::_Future?] dynamic x) → void {}
-static method foo2_a2([@vm.inferred-type.metadata=#lib::B?] dynamic x) → void {}
-static method foo2_a3(dynamic x) → void {}
-static method foo2_a4(dynamic x) → void {}
+static method foo2_a1([@vm.inferred-type.metadata=dart.async::_Future?] dynamic x) → void {
+  self::use(x);
+}
+static method foo2_a2([@vm.inferred-type.metadata=#lib::B?] dynamic x) → void {
+  self::use(x);
+}
+static method foo2_a3(dynamic x) → void {
+  self::use(x);
+}
+static method foo2_a4(dynamic x) → void {
+  self::use(x);
+}
 static method foo2([@vm.inferred-type.metadata=dart.async::_Future?] asy::Future<self::A*>* a1, [@vm.inferred-type.metadata=#lib::B?] self::A* a2, FutureOr<self::A*>* a3, FutureOr<self::A*>* a4) → void {
   self::foo2_a1(a1);
   self::foo2_a2(a2);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
index 089aa81..387080e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_cycle.dart.expect
@@ -67,8 +67,8 @@
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method super_foobar2([@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData) → dynamic {
     super.{self::StreamView::foobar}(onData);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method super_foobar3({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → dynamic {
-    super.{self::StreamView::foobar}(onData, onError: onError);
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method super_foobar3() → dynamic {
+    super.{self::StreamView::foobar}(#C1, onError: #C1);
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13]  get super_stream() → self::Stream*
     return [@vm.inferred-type.metadata=!] super.{self::StreamView::_stream};
@@ -81,28 +81,28 @@
 static method round0() → void {
   new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
 }
-static method round1({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1}) → void {
+static method round1() → void {
   self::ByteStream* x = new self::ByteStream::•(new self::ByteStream::•(new self::_GeneratedStreamImpl::•()));
-  [@vm.direct-call.metadata=#lib::ByteStream.super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(onData);
+  [@vm.direct-call.metadata=#lib::ByteStream.super_foobar1] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar1}(#C1);
 }
-static method round2({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → void {
+static method round2() → void {
   new self::_ControllerStream::•();
   self::Stream* x = new self::_GeneratedStreamImpl::•();
   x = new self::ByteStream::•(x);
-  [@vm.direct-call.metadata=#lib::StreamView.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(onData, onError: onError);
+  [@vm.direct-call.metadata=#lib::StreamView.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(#C1, onError: #C1);
 }
-static method round3({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::Function* onError = #C1}) → void {
+static method round3() → void {
   self::Stream* x = new self::_GeneratedStreamImpl::•();
   x = new self::ByteStream::•(x);
   x = new self::_ControllerStream::•();
-  [@vm.direct-call.metadata=#lib::_StreamImpl.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(onData, onError: onError);
+  [@vm.direct-call.metadata=#lib::_StreamImpl.foobar] [@vm.inferred-type.metadata=!? (skip check)] x.{self::Stream::foobar}(#C1, onError: #C1);
 }
-static method round4({[@vm.inferred-type.metadata=dart.core::Null? (value: null)] (dynamic) →* void onData = #C1}) → void {
+static method round4() → void {
   self::ByteStream* x = new self::ByteStream::•(new self::_ControllerStream::•());
   self::Stream* y = [@vm.direct-call.metadata=#lib::ByteStream.super_stream] [@vm.inferred-type.metadata=!] x.{self::ByteStream::super_stream};
   self::Stream* z = [@vm.direct-call.metadata=#lib::StreamView._stream] [@vm.inferred-type.metadata=!] x.{self::StreamView::_stream};
   if([@vm.direct-call.metadata=dart.core::Object.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] y.{self::Stream::==}(z)) {
-    [@vm.direct-call.metadata=#lib::ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(onData);
+    [@vm.direct-call.metadata=#lib::ByteStream.super_foobar2] [@vm.inferred-type.metadata=!? (skip check)] x.{self::ByteStream::super_foobar2}(#C1);
   }
 }
 static method round5() → void {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
index a639710..0fd6e10 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists.dart.expect
@@ -13,15 +13,15 @@
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7]  final field core::List<core::int*>* filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::filled<core::int*>(2, 0);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:8]  final field core::List<core::int*>* filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::filled<core::int*>(2, 0);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:9]  final field core::List<core::int*>* filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::filled<core::int*>(2, 0);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:10]  final field core::List<core::int*>* filledFactory4 = let core::int* #t1 = 2 in let core::int* #t2 = 0 in let core::bool #t3 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int*>(#t1, #t2, #t3);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:10]  final field core::List<core::int*>* filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int*>(2, 0, #t1);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11]  final field core::List<core::int*>* filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::•<core::int*>(2);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:12]  final field core::List<core::int*>* filledFactory6 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::•<core::int*>(2);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13]  final field core::List<core::int*>* filledFactory7 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::•<core::int*>(2);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:14]  final field core::List<core::int*>* filledFactory8 = let core::int* #t4 = 2 in let core::Null? #t5 = null in let core::bool #t6 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int*>(#t4, #t5, #t6);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:14]  final field core::List<core::int*>* filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int*>(2, null, #t2);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:15]  final field core::List<core::int*>* generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::generate<core::int*>(2, (core::int* i) → core::int* => i);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:16]  final field core::List<core::int*>* generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::_GrowableList::generate<core::int*>(2, (core::int* i) → core::int* => i);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:17]  final field core::List<core::int*>* generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int*>] core::_List::generate<core::int*>(2, (core::int* i) → core::int* => i);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:18]  final field core::List<core::int*>* generateFactory4 = let core::int* #t7 = 2 in let (core::int*) →* core::int* #t8 = (core::int* i) → core::int* => i in let core::bool #t9 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int*>(#t7, #t8, #t9);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:18]  final field core::List<core::int*>* generateFactory4 = let final (core::int*) →* core::int* #t3 = (core::int* i) → core::int* => i in let final core::bool #t4 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int*>(2, #t3, #t4);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int*>*>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:19]  final field core::List<core::List<core::int*>*>* generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int*>*>] core::_GrowableList::generate<core::List<core::int*>*>(2, (core::int* _) → core::List<core::int*>* => <core::int*>[]);
   synthetic constructor •() → self::A*
     : super core::Object::•()
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect
index fa6d7c9..8a54bb1 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/lists_nnbd.dart.expect
@@ -11,15 +11,15 @@
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  final field core::List<core::int> filledFactory1 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6]  final field core::List<core::int> filledFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::filled<core::int>(2, 0);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:7]  final field core::List<core::int> filledFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::filled<core::int>(2, 0);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:8]  final field core::List<core::int> filledFactory4 = let core::int #t1 = 2 in let core::int #t2 = 0 in let core::bool #t3 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(#t1, #t2, #t3);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:8]  final field core::List<core::int> filledFactory4 = let final core::bool #t1 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int>(2, 0, #t1);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:9]  final field core::List<core::int?> filledFactory5 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:10]  final field core::List<core::int?> filledFactory6 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int?>] core::_GrowableList::•<core::int?>(2);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11]  final field core::List<core::int?> filledFactory7 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int?>] core::_List::•<core::int?>(2);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:12]  final field core::List<core::int?> filledFactory8 = let core::int #t4 = 2 in let core::Null? #t5 = null in let core::bool #t6 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(#t4, #t5, #t6);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:12]  final field core::List<core::int?> filledFactory8 = let final core::bool #t2 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::filled<core::int?>(2, null, #t2);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:13]  final field core::List<core::int> generateFactory1 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:14]  final field core::List<core::int> generateFactory2 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int>] core::_GrowableList::generate<core::int>(2, (core::int i) → core::int => i);
 [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:15]  final field core::List<core::int> generateFactory3 = [@vm.inferred-type.metadata=dart.core::_List<dart.core::int>] core::_List::generate<core::int>(2, (core::int i) → core::int => i);
-[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:16]  final field core::List<core::int> generateFactory4 = let core::int #t7 = 2 in let (core::int) → core::int #t8 = (core::int i) → core::int => i in let core::bool #t9 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(#t7, #t8, #t9);
+[@vm.inferred-type.metadata=!] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:16]  final field core::List<core::int> generateFactory4 = let final (core::int) → core::int #t3 = (core::int i) → core::int => i in let final core::bool #t4 = _in::unsafeCast<core::bool>([@vm.inferred-type.metadata=dart.core::bool] self::nonConstant()) in [@vm.inferred-type.metadata=!] core::List::generate<core::int>(2, #t3, #t4);
 [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:17]  final field core::List<core::List<core::int>> generateFactory5 = [@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::List<dart.core::int>>] core::_GrowableList::generate<core::List<core::int>>(2, (core::int _) → core::List<core::int> => <core::int>[]);
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
index 1eb445c..4aff357 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/named_params_shaking_test.dart.expect
@@ -9,15 +9,15 @@
 import "package:expect/expect.dart";
 
 abstract class TestNamedOrderBase extends core::Object {
-[@vm.unboxing-info.metadata=(i)->b]  constructor •([@vm.inferred-type.metadata=int] dynamic w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → self::TestNamedOrderBase*
+[@vm.unboxing-info.metadata=(i,i,i,i)->b]  constructor •([@vm.inferred-type.metadata=int] dynamic w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → self::TestNamedOrderBase*
     : super core::Object::•() {
-    let core::int* #t1 = _in::unsafeCast<core::int*>(w) in let core::int* #t2 = z in let core::int* #t3 = y in let core::int* #t4 = x in self::testNamedOrder(#t1, #t4, #t3, #t2);
+    self::testNamedOrder(_in::unsafeCast<core::int*>(w), x, y, z);
   }
 }
 class TestNamedOrderSub extends self::TestNamedOrderBase {
 [@vm.inferred-type.metadata=int] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i)->i]  field core::int* x;
   constructor •() → self::TestNamedOrderSub*
-    : self::TestNamedOrderSub::x = [@vm.inferred-type.metadata=int] self::dec(), dynamic #t5 = [@vm.inferred-type.metadata=int] self::inc(), dynamic #t6 = [@vm.inferred-type.metadata=int] self::inc(), dynamic #t7 = [@vm.inferred-type.metadata=int] self::inc(), dynamic #t8 = [@vm.inferred-type.metadata=int] self::dec(), super self::TestNamedOrderBase::•(#t5, #t8, #t7, #t6) {
+    : self::TestNamedOrderSub::x = [@vm.inferred-type.metadata=int] self::dec(), final core::int* #t1 = [@vm.inferred-type.metadata=int] self::inc(), final core::int* #t2 = [@vm.inferred-type.metadata=int] self::inc(), final core::int* #t3 = [@vm.inferred-type.metadata=int] self::inc(), final core::int* #t4 = [@vm.inferred-type.metadata=int] self::dec(), super self::TestNamedOrderBase::•(#t1, #t4, #t3, #t2) {
     exp::Expect::equals([@vm.direct-call.metadata=#lib::TestNamedOrderSub.x] [@vm.inferred-type.metadata=int] this.{self::TestNamedOrderSub::x}, 0);
   }
 }
@@ -26,14 +26,14 @@
   return self::global = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.+??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::+}(1);
 [@vm.unboxing-info.metadata=()->i]static method dec() → core::int*
   return self::global = [@vm.inferred-type.metadata=int] math::max<core::int*>(0, self::global = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.-??] [@vm.inferred-type.metadata=int (skip check)] [@vm.inferred-type.metadata=int?] self::global.{core::num::-}(1));
-[@vm.unboxing-info.metadata=(i)->b]static method testNamedOrder([@vm.inferred-type.metadata=int] core::int* w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → void {
+[@vm.unboxing-info.metadata=(i,i,i,i)->b]static method testNamedOrder([@vm.inferred-type.metadata=int] core::int* w, [@vm.inferred-type.metadata=int] core::int* x, [@vm.inferred-type.metadata=int] core::int* y, [@vm.inferred-type.metadata=int] core::int* z) → void {
   exp::Expect::equals(w, 1);
   exp::Expect::equals(z, 2);
   exp::Expect::equals(y, 3);
   exp::Expect::equals(x, 2);
 }
 static method main() → dynamic {
-  let core::int* #t9 = [@vm.inferred-type.metadata=int] self::inc() in let core::int* #t10 = [@vm.inferred-type.metadata=int] self::inc() in let core::int* #t11 = [@vm.inferred-type.metadata=int] self::inc() in let core::int* #t12 = [@vm.inferred-type.metadata=int] self::dec() in self::testNamedOrder(#t9, #t12, #t11, #t10);
+  let final core::int* #t5 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int* #t6 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int* #t7 = [@vm.inferred-type.metadata=int] self::inc() in let final core::int* #t8 = [@vm.inferred-type.metadata=int] self::dec() in self::testNamedOrder(#t5, #t8, #t7, #t6);
   self::global = 1;
   new self::TestNamedOrderSub::•();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index c1f1292e..5b69347 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -39,7 +39,7 @@
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  abstract method foo() → dynamic;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  abstract get bar() → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i)->b]  abstract method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4 = #C1, dynamic a5 = #C1]) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i,i)->b]  abstract method bazz(dynamic a1, dynamic a2, dynamic a3, dynamic a4) → dynamic;
 }
 class B extends self::A {
   synthetic constructor •() → self::B*
@@ -49,11 +49,11 @@
     return new self::T1::•();
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  no-such-method-forwarder get bar() → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  no-such-method-forwarder method foo() → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i)->b]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic a5 = #C1]) → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i,i)->b]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4) → dynamic
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::B.noSuchMethod] [@vm.inferred-type.metadata=#lib::T1 (skip check)] this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C2, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, #C7]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C*
@@ -68,11 +68,11 @@
     : super self::C::•()
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  no-such-method-forwarder get bar() → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  no-such-method-forwarder method foo() → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i)->b]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [[@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4 = #C1, [@vm.inferred-type.metadata=dart.core::Null? (value: null)] dynamic a5 = #C1]) → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C7, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, a5]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5] [@vm.unboxing-info.metadata=(i,i,i,i)->b]  no-such-method-forwarder method bazz([@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic a1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic a2, [@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] dynamic a3, [@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] dynamic a4) → dynamic
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::C.noSuchMethod] [@vm.inferred-type.metadata=#lib::T2 (skip check)] this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#C6, 0, #C2, core::List::unmodifiable<dynamic>(<dynamic>[a1, a2, a3, a4, #C7]), [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
 }
 class E extends core::Object implements self::A {
   synthetic constructor •() → self::E*
@@ -82,7 +82,7 @@
     return new self::T4::•();
   }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  no-such-method-forwarder get bar() → dynamic
-    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E.noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 1, #C3, #C4, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C5))));
+    return _in::unsafeCast<dynamic>([@vm.direct-call.metadata=#lib::E.noSuchMethod] [@vm.inferred-type.metadata=#lib::T4 (skip check)] this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dart.core::Symbol*, dynamic>] core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))));
 }
 class F extends core::Object {
   synthetic constructor •() → self::F*
@@ -104,7 +104,7 @@
   synthetic constructor •() → self::H*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9]  method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C1, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C1}) → dynamic
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8,getterSelectorId:9]  method foo({[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] dynamic left = #C7, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic right = #C7}) → dynamic
     return new self::T6::•();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7]  method noSuchMethod(core::Invocation* invocation) → dynamic {
     return new self::T7::•();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
index 9d38510..d80f88a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_check_elimination_nnbd.dart.expect
@@ -11,7 +11,7 @@
     : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
     ;
 }
-[@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = let core::String #t1 = "hi" in let core::String #t2 = "bye" in new self::A::•(#t1, #t2);
+[@vm.inferred-type.metadata=#lib::A?]static field self::A staticField = new self::A::•("hi", "bye");
 static method testNonNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
   return _in::unsafeCast<core::String>([@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable});
 static method testNullable([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
@@ -19,7 +19,7 @@
 static method testAlwaysNull([@vm.inferred-type.metadata=#lib::A?] self::A a) → dynamic
   return [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull}!;
 static method main() → void {
-  final core::List<self::A> list = <self::A>[let core::String #t3 = "foo" in let core::Null? #t4 = null in let core::Null? #t5 = null in new self::A::•(#t3, #t4, alwaysNull: #t5), self::staticField];
+  final core::List<self::A> list = <self::A>[new self::A::•("foo", null, alwaysNull: null), self::staticField];
   {
     core::Iterator<self::A> :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A>] list.{core::Iterable::iterator};
     for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
index 1e8033d2..615c0d7 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/null_test_elimination.dart.expect
@@ -11,9 +11,9 @@
     : self::A::nonNullable = nonNullable, self::A::nullable = nullable, self::A::alwaysNull = alwaysNull, super core::Object::•()
     ;
 }
-[@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = let core::String* #t1 = "hi" in let core::String* #t2 = "bye" in new self::A::•(#t1, #t2);
+[@vm.inferred-type.metadata=#lib::A?]static field self::A* staticField = new self::A::•("hi", "bye");
 static method testNonNullableIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
-  if(let dynamic #t3 = [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) {
+  if(let dynamic #t1 = [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) {
     core::print("null");
   }
 }
@@ -23,12 +23,12 @@
   }
 }
 static method testAlwaysNullIf1([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
-  if(let dynamic #t4 = [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) {
+  if(let dynamic #t2 = [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) {
     core::print("null");
   }
 }
 static method testNonNullableIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
-  if(!(let dynamic #t5 = [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+  if(!(let dynamic #t3 = [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
     core::print("not null");
   }
 }
@@ -38,20 +38,20 @@
   }
 }
 static method testAlwaysNullIf2([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic {
-  if(!(let dynamic #t6 = [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
+  if(!(let dynamic #t4 = [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) && _in::unsafeCast<core::bool*>([@vm.inferred-type.metadata=dart.core::bool] self::someCondition())) {
     core::print("not null");
   }
 }
 static method testNonNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
-  return !(let dynamic #t7 = [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) ?{core::String*} "not null" : "null";
+  return !(let dynamic #t5 = [@vm.direct-call.metadata=#lib::A.nonNullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString] a.{self::A::nonNullable} in false) ?{core::String*} "not null" : "null";
 static method testNullableCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
   return ![@vm.direct-call.metadata=#lib::A.nullable??] [@vm.inferred-type.metadata=dart.core::_OneByteString?] a.{self::A::nullable}.{core::String::==}(null) ?{core::String*} "not null" : "null";
 static method testAlwaysNullCondExpr([@vm.inferred-type.metadata=#lib::A?] self::A* a) → dynamic
-  return !(let dynamic #t8 = [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) ?{core::String*} "not null" : "null";
+  return !(let dynamic #t6 = [@vm.direct-call.metadata=#lib::A.alwaysNull??] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] a.{self::A::alwaysNull} in true) ?{core::String*} "not null" : "null";
 static method someCondition() → dynamic
   return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1);
 static method main() → void {
-  final core::List<self::A*>* list = <self::A*>[let core::String* #t9 = "foo" in let core::Null? #t10 = null in let core::Null? #t11 = null in new self::A::•(#t9, #t10, alwaysNull: #t11), self::staticField];
+  final core::List<self::A*>* list = <self::A*>[new self::A::•("foo", null, alwaysNull: null), self::staticField];
   {
     core::Iterator<self::A*>* :sync-for-iterator = [@vm.direct-call.metadata=dart.core::_GrowableList.iterator] [@vm.inferred-type.metadata=dart._internal::ListIterator<#lib::A*>] list.{core::Iterable::iterator};
     for (; [@vm.direct-call.metadata=dart._internal::ListIterator.moveNext] [@vm.inferred-type.metadata=dart.core::bool (skip check)] :sync-for-iterator.{core::Iterator::moveNext}(); ) {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
index 2e584fa..ad7ce96 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/create_test.dart.expect
@@ -35,14 +35,14 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep", createEmptyInstance: #C1) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", protoName: "barKeep", subBuilder: #C2);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", protoName: "mapKeep", entryClassName: "FooKeep.MapKeepEntry", keyFieldType: #C3, valueFieldType: #C4, valueCreator: #C2);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C5, protoName: "aKeep");
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", protoName: "hasKeep", subBuilder: #C6);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", protoName: "clearKeep", subBuilder: #C7);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C6);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep*
@@ -52,36 +52,36 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::FooKeep*
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
   get barKeep() → self::BarKeep*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
   set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C14
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C13
   get mapKeep() → core::Map<core::String*, self::BarKeep*>*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C16
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C15
   get aKeep() → core::int*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C16
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C15
   set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C18
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C17
   method hasHasKeep() → core::bool*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(5);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C20
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C19
   method clearClearKeep() → void
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}(7);
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep", createEmptyInstance: #C2) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C5, protoName: "aKeep");
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C4);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
@@ -92,19 +92,19 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::BarKeep*
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C11
   get aKeep() → core::int*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C11
   set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep", createEmptyInstance: #C6) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
@@ -113,12 +113,12 @@
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::HasKeep*
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep", createEmptyInstance: #C7) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
@@ -127,7 +127,7 @@
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::ClearKeep*
     return new self::ClearKeep::_();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
index 7ce67f5..a65b51a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/decode_test.dart.expect
@@ -28,14 +28,14 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep", createEmptyInstance: #C1) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", protoName: "barKeep", subBuilder: #C2);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", protoName: "mapKeep", entryClassName: "FooKeep.MapKeepEntry", keyFieldType: #C3, valueFieldType: #C4, valueCreator: #C2);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C5, protoName: "aKeep");
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", protoName: "hasKeep", subBuilder: #C6);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", protoName: "clearKeep", subBuilder: #C7);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C6);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep*
@@ -43,9 +43,9 @@
     ;
   static factory •() → self::FooKeep*
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
-  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList?<dart.core::int*>] core::List<core::int*>* i, [[@vm.inferred-type.metadata=protobuf::_EmptyExtensionRegistry (value: const protobuf::_EmptyExtensionRegistry{})] pro::ExtensionRegistry* r = #C8]) → self::FooKeep*
+  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList?<dart.core::int*>] core::List<core::int*>* i) → self::FooKeep*
     return let final self::FooKeep* #t2 = [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::GeneratedMessage::mergeFromBuffer}(i, r);
+      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::GeneratedMessage::mergeFromBuffer}(i, #C7);
     } =>#t2;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::FooKeep*
     return let final self::FooKeep* #t3 = [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::•() in block {
@@ -53,28 +53,28 @@
     } =>#t3;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::FooKeep*
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C13
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C12
   get barKeep() → self::BarKeep*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  @#C15
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  @#C14
   get mapKeep() → core::Map<core::String*, self::BarKeep*>*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C17
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C16
   get aKeep() → core::int*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C19
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C18
   method hasHasKeep() → core::bool*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(5);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C21
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C20
   method clearClearKeep() → void
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}(7);
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("BarKeep", createEmptyInstance: #C2) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C5, protoName: "aKeep");
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C4);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
@@ -89,15 +89,15 @@
     } =>#t5;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::BarKeep*
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11] [@vm.unboxing-info.metadata=()->i]  @#C13
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:11] [@vm.unboxing-info.metadata=()->i]  @#C12
   get aKeep() → core::int*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t6 = new pro::BuilderInfo::•("HasKeep", createEmptyInstance: #C6) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t6 = new pro::BuilderInfo::•("HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t6.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t6.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t6;
@@ -112,12 +112,12 @@
     } =>#t7;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::HasKeep*
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t8 = new pro::BuilderInfo::•("ClearKeep", createEmptyInstance: #C7) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t8 = new pro::BuilderInfo::•("ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t8.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t8.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t8;
@@ -132,7 +132,7 @@
     } =>#t9;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::ClearKeep*
     return new self::ClearKeep::_();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
index ebf9b06..22768c2 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/encode_all_fields.dart.expect
@@ -42,14 +42,14 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep", createEmptyInstance: #C1) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", protoName: "barKeep", subBuilder: #C2);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", protoName: "mapKeep", entryClassName: "FooKeep.MapKeepEntry", keyFieldType: #C3, valueFieldType: #C4, valueCreator: #C2);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::ZopDrop*>(4, "mapDrop", protoName: "mapDrop", entryClassName: "FooKeep.MapDropEntry", keyFieldType: #C3, valueFieldType: #C4, valueCreator: #C5);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C6, protoName: "aKeep");
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", protoName: "hasKeep", subBuilder: #C7);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", protoName: "clearKeep", subBuilder: #C8);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::ZopDrop*>(4, "mapDrop", "FooKeep.MapDropEntry", #C2, "mapDrop", #C4, #C3);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C6);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C7);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep*
@@ -59,36 +59,36 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::FooKeep*
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2]  @#C13
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2]  @#C12
   set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  @#C15
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  @#C14
   get mapKeep() → core::Map<core::String*, self::BarKeep*>*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C17
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C16
   get mapDrop() → core::Map<core::String*, self::ZopDrop*>*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::ZopDrop*>(3);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5] [@vm.unboxing-info.metadata=(i)->b]  @#C19
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5] [@vm.unboxing-info.metadata=(i)->b]  @#C18
   set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6]  @#C21
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6]  @#C20
   set hasKeep([@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(6, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7]  @#C23
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7]  @#C22
   set clearKeep([@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(7, v);
   }
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep", createEmptyInstance: #C2) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C6, protoName: "aKeep");
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(2, "bDrop", #C6, protoName: "bDrop");
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(2, "bDrop", #C5);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
   constructor _() → self::BarKeep*
@@ -98,20 +98,20 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::BarKeep*
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] [@vm.unboxing-info.metadata=(i)->b]  @#C13
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:8] [@vm.unboxing-info.metadata=(i)->b]  @#C12
   set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9] [@vm.unboxing-info.metadata=(i)->b]  @#C25
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9] [@vm.unboxing-info.metadata=(i)->b]  @#C24
   set bDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 4)] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(1, v);
   }
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep", createEmptyInstance: #C7) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
@@ -122,12 +122,12 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::HasKeep] self::HasKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::HasKeep*
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep", createEmptyInstance: #C8) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
@@ -138,13 +138,13 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::ClearKeep] self::ClearKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C11
+  @#C10
   static method create() → self::ClearKeep*
     return new self::ClearKeep::_();
 }
 class ZopDrop extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t5 = new pro::BuilderInfo::•("ZopDrop", createEmptyInstance: #C5) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::a}<core::int*>(1, "aDrop", #C6, protoName: "aDrop");
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t5 = new pro::BuilderInfo::•("ZopDrop") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::a}<core::int*>(1, "aDrop", #C5);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t5;
   constructor _() → self::ZopDrop*
@@ -154,10 +154,10 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::ZopDrop] self::ZopDrop::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ZopDrop::_i;
-  @#C11
+  @#C10
   static method create() → self::ZopDrop*
     return new self::ZopDrop::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10] [@vm.unboxing-info.metadata=(i)->b]  @#C13
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:10] [@vm.unboxing-info.metadata=(i)->b]  @#C12
   set aDrop([@vm.inferred-type.metadata=dart.core::_Smi (value: 3)] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
index b0155db..15020be 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/freeze_test.dart.expect
@@ -39,14 +39,14 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class FooKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep", createEmptyInstance: #C1) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", protoName: "barKeep", subBuilder: #C2);
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("FooKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::BarKeep*>(1, "barKeep", #C1);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", protoName: "mapKeep", entryClassName: "FooKeep.MapKeepEntry", keyFieldType: #C3, valueFieldType: #C4, valueCreator: #C2);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.m] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::m}<core::String*, self::BarKeep*>(3, "mapKeep", "FooKeep.MapKeepEntry", #C2, "mapKeep", #C1, #C3);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C5, protoName: "aKeep");
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", protoName: "hasKeep", subBuilder: #C6);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", protoName: "clearKeep", subBuilder: #C7);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::a}<core::int*>(5, "aKeep", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::HasKeep*>(6, "hasKeep", #C5);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::aOM}<self::ClearKeep*>(7, "clearKeep", #C6);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::FooKeep*
@@ -56,36 +56,36 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::FooKeep] self::FooKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::FooKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::FooKeep*
     return new self::FooKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
   get barKeep() → self::BarKeep*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getN] [@vm.inferred-type.metadata=foo.pb.dart::BarKeep? (skip check)] this.{pro::GeneratedMessage::$_getN}<self::BarKeep*>(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  @#C11
   set barKeep([@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.setField] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::setField}(1, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C14
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4]  @#C13
   get mapKeep() → core::Map<core::String*, self::BarKeep*>*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getMap] [@vm.inferred-type.metadata=! (skip check)] this.{pro::GeneratedMessage::$_getMap}<core::String*, self::BarKeep*>(2);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C16
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  @#C15
   get aKeep() → core::int*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(4);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C16
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(i)->b]  @#C15
   set aKeep([@vm.inferred-type.metadata=dart.core::_Smi (value: 43)] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(4, v);
   }
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C18
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8]  @#C17
   method hasHasKeep() → core::bool*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(5);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C20
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  @#C19
   method clearClearKeep() → void
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.clearField] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] this.{pro::GeneratedMessage::clearField}(7);
 }
 class BarKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep", createEmptyInstance: #C2) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C5, protoName: "aKeep");
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t2 = new pro::BuilderInfo::•("BarKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.a] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::a}<core::int*>(1, "aKeep", #C4);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t2;
@@ -96,19 +96,19 @@
     return [@vm.inferred-type.metadata=foo.pb.dart::BarKeep] self::BarKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::BarKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::BarKeep*
     return new self::BarKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=()->i]  @#C11
   get aKeep() → core::int*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_getIZ] [@vm.inferred-type.metadata=int (skip check)] this.{pro::GeneratedMessage::$_getIZ}(0);
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C12
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12] [@vm.unboxing-info.metadata=(i)->b]  @#C11
   set aKeep([@vm.inferred-type.metadata=dart.core::_Smi] core::int* v) → void {
     [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_setSignedInt32] [@vm.inferred-type.metadata=!? (skip check)] this.{pro::GeneratedMessage::$_setSignedInt32}(0, v);
   }
 }
 class HasKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep", createEmptyInstance: #C6) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("HasKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t3;
@@ -117,12 +117,12 @@
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::HasKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::HasKeep*
     return new self::HasKeep::_();
 }
 class ClearKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep", createEmptyInstance: #C7) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t4 = new pro::BuilderInfo::•("ClearKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.add] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::add}<core::Null?>(0, null, null, null, null, null, null);
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t4;
@@ -131,7 +131,7 @@
     ;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::ClearKeep::_i;
-  @#C10
+  @#C9
   static method create() → self::ClearKeep*
     return new self::ClearKeep::_();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
index c392e78..599d0eb 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/protobuf_handler/lib/name_mangling_test.dart.expect
@@ -21,7 +21,7 @@
 import "package:protobuf/protobuf.dart" as $pb;
 
 class AKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = let core::String* #t2 = "AKeep" in let () →* self::AKeep* #t3 = #C1 in new pro::BuilderInfo::•(#t2, #t3) in block {
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t1 = new pro::BuilderInfo::•("AKeep") in block {
     [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t1.{pro::BuilderInfo::hasRequiredFields} = false;
   } =>#t1;
   constructor _() → self::AKeep*
@@ -30,39 +30,39 @@
   static factory •() → self::AKeep*
     return [@vm.inferred-type.metadata=name_mangling.pb.dart::AKeep] self::AKeep::create();
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::AKeep*
-    return let final self::AKeep* #t4 = [@vm.inferred-type.metadata=name_mangling.pb.dart::AKeep] self::AKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t4;
+    return let final self::AKeep* #t2 = [@vm.inferred-type.metadata=name_mangling.pb.dart::AKeep] self::AKeep::•() in block {
+      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t2.{pro::GeneratedMessage::mergeFromMessage}(this);
+    } =>#t2;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::AKeep::_i;
-  @#C4
+  @#C3
   static method create() → self::AKeep*
     return new self::AKeep::_();
 }
 class NameManglingKeep extends pro::GeneratedMessage {
-[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t5 = let core::String* #t6 = "NameManglingKeep" in let () →* self::NameManglingKeep* #t7 = #C5 in new pro::BuilderInfo::•(#t6, #t7) in block {
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::aOM}<self::AKeep*>(10, "clone", subBuilder: #C1);
-    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::BuilderInfo::hasRequiredFields} = false;
-  } =>#t5;
+[@vm.inferred-type.metadata=protobuf::BuilderInfo?]  static final field pro::BuilderInfo* _i = let final pro::BuilderInfo* #t3 = new pro::BuilderInfo::•("NameManglingKeep") in block {
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.aOM] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::aOM}<self::AKeep*>(10, "clone", #C4);
+    [@vm.direct-call.metadata=protobuf::BuilderInfo.hasRequiredFields] [@vm.inferred-type.metadata=!? (skip check)] #t3.{pro::BuilderInfo::hasRequiredFields} = false;
+  } =>#t3;
   constructor _() → self::NameManglingKeep*
     : super pro::GeneratedMessage::•()
     ;
   static factory •() → self::NameManglingKeep*
     return [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::create();
-  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::List<core::int*>* i, [[@vm.inferred-type.metadata=protobuf::_EmptyExtensionRegistry (value: const protobuf::_EmptyExtensionRegistry{})] pro::ExtensionRegistry* r = #C6]) → self::NameManglingKeep*
-    return let final self::NameManglingKeep* #t8 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::create() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t8.{pro::GeneratedMessage::mergeFromBuffer}(i, r);
-    } =>#t8;
+  static factory fromBuffer([@vm.inferred-type.metadata=dart.core::_GrowableList<dart.core::int*>] core::List<core::int*>* i) → self::NameManglingKeep*
+    return let final self::NameManglingKeep* #t4 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::create() in block {
+      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromBuffer] [@vm.inferred-type.metadata=!? (skip check)] #t4.{pro::GeneratedMessage::mergeFromBuffer}(i, #C5);
+    } =>#t4;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method clone() → self::NameManglingKeep*
-    return let final self::NameManglingKeep* #t9 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::•() in block {
-      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t9.{pro::GeneratedMessage::mergeFromMessage}(this);
-    } =>#t9;
+    return let final self::NameManglingKeep* #t5 = [@vm.inferred-type.metadata=name_mangling.pb.dart::NameManglingKeep] self::NameManglingKeep::•() in block {
+      [@vm.direct-call.metadata=protobuf::GeneratedMessage.mergeFromMessage] [@vm.inferred-type.metadata=!? (skip check)] #t5.{pro::GeneratedMessage::mergeFromMessage}(this);
+    } =>#t5;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]  get info_() → pro::BuilderInfo*
     return [@vm.inferred-type.metadata=protobuf::BuilderInfo?] self::NameManglingKeep::_i;
-  @#C4
+  @#C3
   static method create() → self::NameManglingKeep*
     return new self::NameManglingKeep::_();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5]  @#C8
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:4,getterSelectorId:5]  @#C7
   method hasClone_10() → core::bool*
     return [@vm.direct-call.metadata=protobuf::GeneratedMessage.$_has] [@vm.inferred-type.metadata=dart.core::bool (skip check)] this.{pro::GeneratedMessage::$_has}(0);
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
index fa2eda6..413720d 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/set_map_constructor_concrete.dart.expect
@@ -9,15 +9,15 @@
 [@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dynamic>]static field core::Set<dynamic>* globalSet = new col::_CompactLinkedHashSet::•<dynamic>();
 [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet?<dynamic>]static field core::Set<dynamic>* identitySet = [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet<dynamic>] col::LinkedHashSet::identity<dynamic>();
 [@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dart.core::String*>]static field core::Set<core::String*>* linkedSet = new col::_CompactLinkedHashSet::•<core::String*>();
-static field core::Set<core::String*>* linkedIdentitySet = let (core::Object?, core::Object?) → core::bool #t1 = #C1 in let (core::Object?) → core::int #t2 = #C2 in [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String*>(#t1, #t2);
-static field core::Set<core::String*>* linkedCustomSet = let (core::String*, core::String*) →* core::bool* #t3 = (core::String* a, core::String* b) → core::bool* => a.{core::String::==}(b) in let (core::String*) →* core::int* #t4 = (core::String* o) → core::int* => o.{core::String::hashCode} in let (dynamic) →* core::bool* #t5 = (dynamic o) → core::bool* => true in [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String*>(#t3, #t4, isValidKey: #t5);
+static field core::Set<core::String*>* linkedIdentitySet = [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String*>(#C1, #C2);
+static field core::Set<core::String*>* linkedCustomSet = let final (core::String*, core::String*) →* core::bool* #t1 = (core::String* a, core::String* b) → core::bool* => a.{core::String::==}(b) in let final (core::String*) →* core::int* #t2 = (core::String* o) → core::int* => o.{core::String::hashCode} in let final (dynamic) →* core::bool* #t3 = (dynamic o) → core::bool* => true in [@vm.inferred-type.metadata=!] col::LinkedHashSet::•<core::String*>(#t1, #t2, isValidKey: #t3);
 [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap?<dynamic, dynamic>]static field core::Map<dynamic, dynamic>* globalMap = [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap<dynamic, dynamic>] core::Map::•<dynamic, dynamic>();
 [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashMap?<dynamic, dynamic>]static field core::Map<dynamic, dynamic>* identityMap = [@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashMap<dynamic, dynamic>] col::LinkedHashMap::identity<dynamic, dynamic>();
 [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView?<dynamic, dynamic>]static field core::Map<dynamic, dynamic>* unmodifiableMap = [@vm.inferred-type.metadata=dart.collection::UnmodifiableMapView<dynamic, dynamic>] core::Map::unmodifiable<dynamic, dynamic>([@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashMap?<dynamic, dynamic>] self::identityMap);
 [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap?<dynamic, dynamic>]static field core::Map<dynamic, dynamic>* globalMapLiteral = <dynamic, dynamic>{};
 [@vm.inferred-type.metadata=dart.collection::_InternalLinkedHashMap?<dart.core::String*, dart.core::String*>]static field core::Map<core::String*, core::String*>* linkedMap = new col::_InternalLinkedHashMap::•<core::String*, core::String*>();
-static field core::Map<core::String*, core::String*>* linkedIdentityMap = let (core::Object?, core::Object?) → core::bool #t6 = #C1 in let (core::Object?) → core::int #t7 = #C2 in [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String*, core::String*>(#t6, #t7);
-static field core::Map<core::String*, core::String*>* linkedCustomMap = let (core::String*, core::String*) →* core::bool* #t8 = (core::String* a, core::String* b) → core::bool* => a.{core::String::==}(b) in let (core::String*) →* core::int* #t9 = (core::String* o) → core::int* => o.{core::String::hashCode} in let (dynamic) →* core::bool* #t10 = (dynamic o) → core::bool* => true in [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String*, core::String*>(#t8, #t9, isValidKey: #t10);
+static field core::Map<core::String*, core::String*>* linkedIdentityMap = [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String*, core::String*>(#C1, #C2);
+static field core::Map<core::String*, core::String*>* linkedCustomMap = let final (core::String*, core::String*) →* core::bool* #t4 = (core::String* a, core::String* b) → core::bool* => a.{core::String::==}(b) in let final (core::String*) →* core::int* #t5 = (core::String* o) → core::int* => o.{core::String::hashCode} in let final (dynamic) →* core::bool* #t6 = (dynamic o) → core::bool* => true in [@vm.inferred-type.metadata=!] col::LinkedHashMap::•<core::String*, core::String*>(#t4, #t5, isValidKey: #t6);
 static method main() → dynamic {
   core::print([@vm.inferred-type.metadata=dart.collection::_CompactLinkedHashSet?<dynamic>] self::globalSet);
   core::print([@vm.inferred-type.metadata=dart.collection::_CompactLinkedIdentityHashSet?<dynamic>] self::identitySet);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart
index 4de6f85..726b6c9 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart
@@ -6,6 +6,11 @@
 final bool kFalse = int.parse('1') == 2 ? true : false;
 int get mint => 0xaabbccddaabbccdd;
 int get smiOrMint => kTrue ? 1 : mint;
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
 
 abstract class BI1 {
   int get value;
@@ -86,5 +91,3 @@
   final ubib = UBIB(); // getter returns smiOrMint
   use((kTrue ? ubia : ubib).value);
 }
-
-void use(dynamic object) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
index be40648..4dbd258 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_getters.dart.expect
@@ -69,10 +69,14 @@
     return [@vm.inferred-type.metadata=int] self::smiOrMint;
 }
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
+[@vm.inferred-type.metadata=int?]static field dynamic usedObject;
 [@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
   return -6144092014192636707;
 [@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
+static method use([@vm.inferred-type.metadata=int?] dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] [@vm.inferred-type.metadata=int?] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
 static method main() → dynamic {
   final self::BI1A* bi1a = new self::BI1A::•([@vm.inferred-type.metadata=int] self::smiOrMint);
   final self::BI1B* bi1b = new self::BI1B::•();
@@ -88,4 +92,3 @@
   final self::UBIB* ubib = new self::UBIB::•();
   self::use([@vm.inferred-type.metadata=int]([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::UBI*} ubia : ubib).{self::UBI::value});
 }
-static method use([@vm.inferred-type.metadata=int?] dynamic object) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart
index 8ab5bc9..ff1a20e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart
@@ -6,6 +6,11 @@
 final bool kFalse = int.parse('1') == 2 ? true : false;
 int get mint => 0xaabbccddaabbccdd;
 int get smiOrMint => kTrue ? 1 : mint;
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
 
 class X {}
 
@@ -64,5 +69,3 @@
   use(a.boxedNullableX);
   use(a.boxedX);
 }
-
-void use(dynamic object) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect
index bce3568..65b0969 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_fields.dart.expect
@@ -23,10 +23,14 @@
 }
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
+static field dynamic usedObject;
 [@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
   return -6144092014192636707;
 [@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
+static method use(dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
 static method main() → dynamic {
   final self::A* a = new self::A::•([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
   [@vm.direct-call.metadata=#lib::A.unboxedSmi] [@vm.inferred-type.metadata=!? (skip check)] a.{self::A::unboxedSmi} = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
@@ -48,4 +52,3 @@
   self::use([@vm.direct-call.metadata=#lib::A.boxedNullableX] [@vm.inferred-type.metadata=#lib::X?] a.{self::A::boxedNullableX});
   self::use([@vm.direct-call.metadata=#lib::A.boxedX] [@vm.inferred-type.metadata=#lib::X] a.{self::A::boxedX});
 }
-static method use(dynamic object) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart
index bf63d64..f37b67e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart
@@ -6,6 +6,11 @@
 final bool kFalse = int.parse('1') == 2 ? true : false;
 int get mint => 0xaabbccddaabbccdd;
 int get smiOrMint => kTrue ? 1 : mint;
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
 
 class X {}
 
@@ -42,7 +47,16 @@
       dynamic boxedNonNullableIntOrDouble,
       dynamic boxedNullableIntOrDouble,
       dynamic boxedNullableX,
-      dynamic boxedX) {}
+      dynamic boxedX) {
+    use(unboxedInt);
+    use(unboxedDouble);
+    use(boxedNullableInt);
+    use(boxedNullableDouble);
+    use(boxedNonNullableIntOrDouble);
+    use(boxedNullableIntOrDouble);
+    use(boxedNullableX);
+    use(boxedX);
+  }
 
   dynamic returnUnboxedSmi(X ignored) => 1;
   dynamic returnUnboxedInt(X ignored) => 1;
@@ -65,7 +79,16 @@
       dynamic boxedNonNullableIntOrDouble,
       dynamic boxedNullableIntOrDouble,
       dynamic boxedNullableX,
-      dynamic boxedX) {}
+      dynamic boxedX) {
+    use(unboxedInt);
+    use(unboxedDouble);
+    use(boxedNullableInt);
+    use(boxedNullableDouble);
+    use(boxedNonNullableIntOrDouble);
+    use(boxedNullableIntOrDouble);
+    use(boxedNullableX);
+    use(boxedX);
+  }
 
   dynamic returnUnboxedSmi(X ignored) => 2;
   dynamic returnUnboxedInt(X ignored) => mint;
@@ -88,7 +111,16 @@
       dynamic boxedNonNullableIntOrDouble,
       dynamic boxedNullableIntOrDouble,
       dynamic boxedNullableX,
-      dynamic boxedX) {}
+      dynamic boxedX) {
+    use(unboxedInt);
+    use(unboxedDouble);
+    use(boxedNullableInt);
+    use(boxedNullableDouble);
+    use(boxedNonNullableIntOrDouble);
+    use(boxedNullableIntOrDouble);
+    use(boxedNullableX);
+    use(boxedX);
+  }
 
   dynamic returnUnboxedSmi(X ignored) => 3;
   dynamic returnUnboxedInt(X ignored) => mint;
@@ -154,5 +186,3 @@
   use(d.returnBoxedNullableX(null));
   use(d.returnBoxedX(null));
 }
-
-void use(dynamic value) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
index e019e26..34bb4b0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method.dart.expect
@@ -8,136 +8,166 @@
     ;
 }
 abstract class Interface extends core::Object {
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,i,d,b,b,b,b,b,b)->b]  abstract method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  abstract method returnUnboxedSmi(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  abstract method returnUnboxedInt(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d]  abstract method returnUnboxedDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  abstract method returnBoxedNullableInt(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  abstract method returnBoxedNullableDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  abstract method returnBoxedIntOrDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  abstract method returnBoxedNullableIntOrDouble(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  abstract method returnBoxedNullableX(self::X* ignored) → dynamic;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  abstract method returnBoxedX(self::X* ignored) → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b]  abstract method takePositional(dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i]  abstract method returnUnboxedSmi() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  abstract method returnUnboxedInt() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=()->d]  abstract method returnUnboxedDouble() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  abstract method returnBoxedNullableInt() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  abstract method returnBoxedNullableDouble() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  abstract method returnBoxedIntOrDouble() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  abstract method returnBoxedNullableIntOrDouble() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  abstract method returnBoxedNullableX() → dynamic;
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  abstract method returnBoxedX() → dynamic;
 }
 class Impl1 extends core::Object implements self::Interface {
   synthetic constructor •() → self::Impl1*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,i,d,b,b,b,b,b,b)->b]  method takePositional([@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedSmi([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b]  method takePositional([@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+    self::use(unboxedInt);
+    self::use(unboxedDouble);
+    self::use(boxedNullableInt);
+    self::use(boxedNullableDouble);
+    self::use(boxedNonNullableIntOrDouble);
+    self::use(boxedNullableIntOrDouble);
+    self::use(boxedNullableX);
+    self::use(boxedX);
+  }
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i]  method returnUnboxedSmi() → dynamic
     return 1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  method returnUnboxedInt() → dynamic
     return 1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d]  method returnUnboxedDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=()->d]  method returnUnboxedDouble() → dynamic
     return 1.1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method returnBoxedNullableInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method returnBoxedNullableInt() → dynamic
     return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method returnBoxedNullableDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method returnBoxedNullableDouble() → dynamic
     return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  method returnBoxedIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  method returnBoxedIntOrDouble() → dynamic
     return 1;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  method returnBoxedNullableIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  method returnBoxedNullableIntOrDouble() → dynamic
     return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  method returnBoxedNullableX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  method returnBoxedNullableX() → dynamic
     return null;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX() → dynamic
     return new self::X::•();
 }
 class BaseImpl2 extends core::Object {
   synthetic constructor •() → self::BaseImpl2*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,i,d,b,b,b,b,b,b)->b]  method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] core::int* unboxedSmi, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedSmi([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b]  method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+    self::use(unboxedInt);
+    self::use(unboxedDouble);
+    self::use(boxedNullableInt);
+    self::use(boxedNullableDouble);
+    self::use(boxedNonNullableIntOrDouble);
+    self::use(boxedNullableIntOrDouble);
+    self::use(boxedNullableX);
+    self::use(boxedX);
+  }
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i]  method returnUnboxedSmi() → dynamic
     return 2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  method returnUnboxedInt() → dynamic
     return [@vm.inferred-type.metadata=int] self::mint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d]  method returnUnboxedDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=()->d]  method returnUnboxedDouble() → dynamic
     return 2.2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method returnBoxedNullableInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method returnBoxedNullableInt() → dynamic
     return 2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method returnBoxedNullableDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method returnBoxedNullableDouble() → dynamic
     return 2.2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  method returnBoxedIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  method returnBoxedIntOrDouble() → dynamic
     return 2.2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  method returnBoxedNullableIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  method returnBoxedNullableIntOrDouble() → dynamic
     return 2;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  method returnBoxedNullableX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  method returnBoxedNullableX() → dynamic
     return new self::X::•();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX() → dynamic
     return new self::X::•();
 }
 class SubImpl3 extends self::BaseImpl2 implements self::Interface {
   synthetic constructor •() → self::SubImpl3*
     : super self::BaseImpl2::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,i,d,b,b,b,b,b,b)->b]  method takePositional([@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=!] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedSmi([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2] [@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b]  method takePositional([@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=!] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+    self::use(unboxedInt);
+    self::use(unboxedDouble);
+    self::use(boxedNullableInt);
+    self::use(boxedNullableDouble);
+    self::use(boxedNonNullableIntOrDouble);
+    self::use(boxedNullableIntOrDouble);
+    self::use(boxedNullableX);
+    self::use(boxedX);
+  }
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i]  method returnUnboxedSmi() → dynamic
     return 3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=()->i]  method returnUnboxedInt() → dynamic
     return [@vm.inferred-type.metadata=int] self::mint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=(b)->d]  method returnUnboxedDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:7,getterSelectorId:8] [@vm.unboxing-info.metadata=()->d]  method returnUnboxedDouble() → dynamic
     return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method returnBoxedNullableInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:9,getterSelectorId:10]  method returnBoxedNullableInt() → dynamic
     return [@vm.inferred-type.metadata=int] self::mint;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method returnBoxedNullableDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:11,getterSelectorId:12]  method returnBoxedNullableDouble() → dynamic
     return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  method returnBoxedIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:13,getterSelectorId:14]  method returnBoxedIntOrDouble() → dynamic
     return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  method returnBoxedNullableIntOrDouble([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:15,getterSelectorId:16]  method returnBoxedNullableIntOrDouble() → dynamic
     return 3.3;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  method returnBoxedNullableX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:17,getterSelectorId:18]  method returnBoxedNullableX() → dynamic
     return new self::X::•();
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX() → dynamic
     return new self::X::•();
 }
+static field dynamic usedObject;
 [@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
   return -6144092014192636707;
+static method use(dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
 static method main() → dynamic {
   final core::List<core::Object*>* values = <core::Object*>[new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•()];
   final self::Impl1* a = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("0")) as self::Impl1*;
   final self::BaseImpl2* b = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("1")) as self::BaseImpl2*;
   final self::SubImpl3* c = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::SubImpl3*;
   final self::Interface* d = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("2")) as self::Interface*;
-  [@vm.direct-call.metadata=#lib::Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1, 1.1, null, null, 1, null, null, new self::X::•());
-  b.{self::BaseImpl2::takePositional}(2, 2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•());
-  [@vm.direct-call.metadata=#lib::SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
-  d.{self::Interface::takePositional}(3, [@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}(null));
-  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}(null));
-  self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}(null));
-  self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnBoxedNullableInt}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedNullableDouble}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedIntOrDouble}(null));
-  self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}(null));
-  self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}(null));
-  self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}(null));
-  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}(null));
-  self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}(null));
-  self::use([@vm.inferred-type.metadata=int?] d.{self::Interface::returnBoxedNullableInt}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableDouble}(null));
-  self::use([@vm.inferred-type.metadata=!] d.{self::Interface::returnBoxedIntOrDouble}(null));
-  self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableIntOrDouble}(null));
-  self::use([@vm.inferred-type.metadata=#lib::X?] d.{self::Interface::returnBoxedNullableX}(null));
-  self::use([@vm.inferred-type.metadata=#lib::X] d.{self::Interface::returnBoxedX}(null));
+  [@vm.direct-call.metadata=#lib::Impl1.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] a.{self::Impl1::takePositional}(1, 1.1, null, null, 1, null, null, new self::X::•());
+  b.{self::BaseImpl2::takePositional}(2, 2.2, 2, 2.2, 2.2, 2, new self::X::•(), new self::X::•());
+  [@vm.direct-call.metadata=#lib::SubImpl3.takePositional??] [@vm.inferred-type.metadata=!? (skip check)] c.{self::SubImpl3::takePositional}([@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
+  d.{self::Interface::takePositional}([@vm.inferred-type.metadata=int] self::mint, 3.3, [@vm.inferred-type.metadata=int] self::mint, 3.3, 3.3, 3.3, new self::X::•(), new self::X::•());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedSmi}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedInt] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnUnboxedInt}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 1.1)] a.{self::Impl1::returnUnboxedDouble}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableInt] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableInt}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableDouble}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 1)] a.{self::Impl1::returnBoxedIntOrDouble}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableIntOrDouble}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedNullableX] [@vm.inferred-type.metadata=dart.core::Null? (skip check) (value: null)] a.{self::Impl1::returnBoxedNullableX}());
+  self::use([@vm.direct-call.metadata=#lib::Impl1.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] a.{self::Impl1::returnBoxedX}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Smi] b.{self::BaseImpl2::returnUnboxedSmi}());
+  self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnUnboxedInt}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnUnboxedDouble}());
+  self::use([@vm.inferred-type.metadata=int] b.{self::BaseImpl2::returnBoxedNullableInt}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedNullableDouble}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Double] b.{self::BaseImpl2::returnBoxedIntOrDouble}());
+  self::use([@vm.inferred-type.metadata=!] b.{self::BaseImpl2::returnBoxedNullableIntOrDouble}());
+  self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedNullableX}());
+  self::use([@vm.inferred-type.metadata=#lib::X] b.{self::BaseImpl2::returnBoxedX}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedSmi] [@vm.inferred-type.metadata=dart.core::_Smi (skip check) (value: 3)] c.{self::SubImpl3::returnUnboxedSmi}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnUnboxedInt}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnUnboxedDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnUnboxedDouble}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableInt] [@vm.inferred-type.metadata=int (skip check)] c.{self::SubImpl3::returnBoxedNullableInt}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableDouble}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedIntOrDouble}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableIntOrDouble] [@vm.inferred-type.metadata=dart.core::_Double (skip check) (value: 3.3)] c.{self::SubImpl3::returnBoxedNullableIntOrDouble}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedNullableX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedNullableX}());
+  self::use([@vm.direct-call.metadata=#lib::SubImpl3.returnBoxedX] [@vm.inferred-type.metadata=#lib::X (skip check)] c.{self::SubImpl3::returnBoxedX}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Smi] d.{self::Interface::returnUnboxedSmi}());
+  self::use([@vm.inferred-type.metadata=int] d.{self::Interface::returnUnboxedInt}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Double] d.{self::Interface::returnUnboxedDouble}());
+  self::use([@vm.inferred-type.metadata=int?] d.{self::Interface::returnBoxedNullableInt}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableDouble}());
+  self::use([@vm.inferred-type.metadata=!] d.{self::Interface::returnBoxedIntOrDouble}());
+  self::use([@vm.inferred-type.metadata=dart.core::_Double?] d.{self::Interface::returnBoxedNullableIntOrDouble}());
+  self::use([@vm.inferred-type.metadata=#lib::X?] d.{self::Interface::returnBoxedNullableX}());
+  self::use([@vm.inferred-type.metadata=#lib::X] d.{self::Interface::returnBoxedX}());
 }
-static method use(dynamic value) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart
index fa87b74..ddbf2a0 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart
@@ -6,6 +6,11 @@
 final bool kFalse = int.parse('1') == 2 ? true : false;
 int get mint => 0xaabbccddaabbccdd;
 int get smiOrMint => kTrue ? 1 : mint;
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
 
 class X {}
 
@@ -42,7 +47,16 @@
       dynamic boxedNonNullableIntOrDouble,
       dynamic boxedNullableIntOrDouble,
       dynamic boxedNullableX,
-      dynamic boxedX) {}
+      dynamic boxedX) {
+    use(unboxedInt);
+    use(unboxedDouble);
+    use(boxedNullableInt);
+    use(boxedNullableDouble);
+    use(boxedNonNullableIntOrDouble);
+    use(boxedNullableIntOrDouble);
+    use(boxedNullableX);
+    use(boxedX);
+  }
 
   dynamic returnUnboxedSmi(X ignored) => 1;
   dynamic returnUnboxedInt(X ignored) => 1;
@@ -65,7 +79,16 @@
       dynamic boxedNonNullableIntOrDouble,
       dynamic boxedNullableIntOrDouble,
       dynamic boxedNullableX,
-      dynamic boxedX) {}
+      dynamic boxedX) {
+    use(unboxedInt);
+    use(unboxedDouble);
+    use(boxedNullableInt);
+    use(boxedNullableDouble);
+    use(boxedNonNullableIntOrDouble);
+    use(boxedNullableIntOrDouble);
+    use(boxedNullableX);
+    use(boxedX);
+  }
 
   dynamic returnUnboxedSmi(X ignored) => 2;
   dynamic returnUnboxedInt(X ignored) => mint;
@@ -88,7 +111,16 @@
       dynamic boxedNonNullableIntOrDouble,
       dynamic boxedNullableIntOrDouble,
       dynamic boxedNullableX,
-      dynamic boxedX) {}
+      dynamic boxedX) {
+    use(unboxedInt);
+    use(unboxedDouble);
+    use(boxedNullableInt);
+    use(boxedNullableDouble);
+    use(boxedNonNullableIntOrDouble);
+    use(boxedNullableIntOrDouble);
+    use(boxedNullableX);
+    use(boxedX);
+  }
 
   dynamic returnUnboxedSmi(X ignored) => 3;
   dynamic returnUnboxedInt(X ignored) => mint;
@@ -166,5 +198,3 @@
   use(d.returnBoxedNullableX);
   use(d.returnBoxedX);
 }
-
-void use(dynamic value) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
index bed2172..0b24d0e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_instance_method_tearoff.dart.expect
@@ -23,7 +23,16 @@
   synthetic constructor •() → self::Impl1*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
+    self::use(unboxedInt);
+    self::use(unboxedDouble);
+    self::use(boxedNullableInt);
+    self::use(boxedNullableDouble);
+    self::use(boxedNonNullableIntOrDouble);
+    self::use(boxedNullableIntOrDouble);
+    self::use(boxedNullableX);
+    self::use(boxedX);
+  }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedSmi(self::X* ignored) → dynamic
     return 1;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedInt(self::X* ignored) → dynamic
@@ -47,7 +56,16 @@
   synthetic constructor •() → self::BaseImpl2*
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] core::int* unboxedSmi, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method takePositional([@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] core::int* unboxedSmi, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic unboxedDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=dart.core::_Double (value: 2.2)] dynamic boxedNonNullableIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+    self::use(unboxedInt);
+    self::use(unboxedDouble);
+    self::use(boxedNullableInt);
+    self::use(boxedNullableDouble);
+    self::use(boxedNonNullableIntOrDouble);
+    self::use(boxedNullableIntOrDouble);
+    self::use(boxedNullableX);
+    self::use(boxedX);
+  }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedSmi([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
     return 2;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedInt([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::X* ignored) → dynamic
@@ -71,7 +89,16 @@
   synthetic constructor •() → self::SubImpl3*
     : super self::BaseImpl2::•()
     ;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {}
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedNonNullableIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
+    self::use(unboxedInt);
+    self::use(unboxedDouble);
+    self::use(boxedNullableInt);
+    self::use(boxedNullableDouble);
+    self::use(boxedNonNullableIntOrDouble);
+    self::use(boxedNullableIntOrDouble);
+    self::use(boxedNullableX);
+    self::use(boxedX);
+  }
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:3,getterSelectorId:4] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedSmi(self::X* ignored) → dynamic
     return 3;
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:5,getterSelectorId:6] [@vm.unboxing-info.metadata=(b)->i]  method returnUnboxedInt(self::X* ignored) → dynamic
@@ -91,8 +118,12 @@
 [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,methodOrSetterSelectorId:19,getterSelectorId:20]  method returnBoxedX(self::X* ignored) → dynamic
     return new self::X::•();
 }
+static field dynamic usedObject;
 [@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
   return -6144092014192636707;
+static method use(dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
 static method main() → dynamic {
   final core::List<core::Object*>* values = <core::Object*>[new self::Impl1::•(), new self::BaseImpl2::•(), new self::SubImpl3::•()];
   final self::Impl1* a = [@vm.direct-call.metadata=dart.core::_GrowableList.[]] [@vm.inferred-type.metadata=!? (skip check)] values.{core::List::[]}([@vm.inferred-type.metadata=int] core::int::parse("0")) as self::Impl1*;
@@ -150,4 +181,3 @@
   self::use(d.{self::Interface::returnBoxedNullableX});
   self::use(d.{self::Interface::returnBoxedX});
 }
-static method use(dynamic value) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
index 49c6b9f..5151f2e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
@@ -6,6 +6,11 @@
 final bool kFalse = int.parse('1') == 2 ? true : false;
 int get mint => 0xaabbccddaabbccdd;
 int get smiOrMint => kTrue ? 1 : mint;
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
 
 class X {}
 
@@ -18,7 +23,16 @@
     dynamic boxedIntOrDouble,
     dynamic boxedNullableIntOrDouble,
     dynamic boxedNullableX,
-    dynamic boxedX) {}
+    dynamic boxedX) {
+  use(unboxedInt);
+  use(unboxedDouble);
+  use(boxedNullableInt);
+  use(boxedNullableDouble);
+  use(boxedIntOrDouble);
+  use(boxedNullableIntOrDouble);
+  use(boxedNullableX);
+  use(boxedX);
+}
 
 void takeOptional(
     [int unboxedSmi,
@@ -29,7 +43,16 @@
     dynamic boxedIntOrDouble,
     dynamic boxedNullableIntOrDouble,
     dynamic boxedNullableX,
-    dynamic boxedX]) {}
+    dynamic boxedX]) {
+  use(unboxedInt);
+  use(unboxedDouble);
+  use(boxedNullableInt);
+  use(boxedNullableDouble);
+  use(boxedIntOrDouble);
+  use(boxedNullableIntOrDouble);
+  use(boxedNullableX);
+  use(boxedX);
+}
 
 void takeNamed(
     {int unboxedSmi,
@@ -40,7 +63,16 @@
     dynamic boxedIntOrDouble,
     dynamic boxedNullableIntOrDouble,
     dynamic boxedNullableX,
-    dynamic boxedX}) {}
+    dynamic boxedX}) {
+  use(unboxedInt);
+  use(unboxedDouble);
+  use(boxedNullableInt);
+  use(boxedNullableDouble);
+  use(boxedIntOrDouble);
+  use(boxedNullableIntOrDouble);
+  use(boxedNullableX);
+  use(boxedX);
+}
 
 dynamic returnUnboxedSmi() => kTrue ? 1 : 2;
 dynamic returnUnboxedInt() => kTrue ? smiOrMint : 2;
@@ -106,5 +138,3 @@
   use(returnBoxedX());
   use(returnBoxedSmiFromEntryPoint());
 }
-
-void use(dynamic value) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
index 8074925..934befa 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
@@ -9,13 +9,44 @@
 }
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
+static field dynamic usedObject;
 [@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
   return -6144092014192636707;
 [@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
-[@vm.unboxing-info.metadata=(i,i,d,b,b,b,b,b,b)->b]static method takePositional([@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
-static method takeOptional([@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
-static method takeNamed([@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi) → void {}
+static method use(dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
+[@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b]static method takePositional([@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+  self::use(unboxedInt);
+  self::use(unboxedDouble);
+  self::use(boxedNullableInt);
+  self::use(boxedNullableDouble);
+  self::use(boxedIntOrDouble);
+  self::use(boxedNullableIntOrDouble);
+  self::use(boxedNullableX);
+  self::use(boxedX);
+}
+[@vm.unboxing-info.metadata=(i,d,b,b,b,b,b,b)->b]static method takeOptional([@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {
+  self::use(unboxedInt);
+  self::use(unboxedDouble);
+  self::use(boxedNullableInt);
+  self::use(boxedNullableDouble);
+  self::use(boxedIntOrDouble);
+  self::use(boxedNullableIntOrDouble);
+  self::use(boxedNullableX);
+  self::use(boxedX);
+}
+[@vm.unboxing-info.metadata=(b,b,b,b,b,b,d,i)->b]static method takeNamed([@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int] dynamic unboxedInt) → void {
+  self::use(unboxedInt);
+  self::use(unboxedDouble);
+  self::use(boxedNullableInt);
+  self::use(boxedNullableDouble);
+  self::use(boxedIntOrDouble);
+  self::use(boxedNullableIntOrDouble);
+  self::use(boxedNullableX);
+  self::use(boxedX);
+}
 [@vm.unboxing-info.metadata=()->i]static method returnUnboxedSmi() → dynamic
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
 [@vm.unboxing-info.metadata=()->i]static method returnUnboxedInt() → dynamic
@@ -40,9 +71,9 @@
 @#C3
 static method takeBoxedSmiFromEntryPoint(core::int* value) → void {}
 static method main() → dynamic {
-  self::takePositional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
-  self::takeOptional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
-  let core::int* #t1 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let core::int* #t2 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let core::double* #t3 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let core::int* #t4 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let core::double* #t5 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let core::num* #t6 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let core::num* #t7 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let self::X* #t8 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let self::X* #t9 = new self::X::•() in self::takeNamed(#t6, #t5, #t4, #t7, #t8, #t9, #t3, #t2, #t1);
+  let final core::int* #t1 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let final core::int* #t2 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double* #t3 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let final core::int* #t4 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double* #t5 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let final core::num* #t6 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num* #t7 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X* #t8 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let final self::X* #t9 = new self::X::•() in self::takePositional(#t2, #t3, #t4, #t5, #t6, #t7, #t8, #t9);
+  let final core::int* #t10 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let final core::int* #t11 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double* #t12 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let final core::int* #t13 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double* #t14 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let final core::num* #t15 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num* #t16 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X* #t17 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let final self::X* #t18 = new self::X::•() in self::takeOptional(#t11, #t12, #t13, #t14, #t15, #t16, #t17, #t18);
+  let final core::int* #t19 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let final core::int* #t20 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let final core::double* #t21 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let final core::int* #t22 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let final core::double* #t23 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let final core::num* #t24 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let final core::num* #t25 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let final self::X* #t26 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let final self::X* #t27 = new self::X::•() in self::takeNamed(#t24, #t23, #t22, #t25, #t26, #t27, #t21, #t20);
   self::takeBoxedSmiFromEntryPoint([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2);
   self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnUnboxedSmi());
   self::use([@vm.inferred-type.metadata=int] self::returnUnboxedInt());
@@ -55,4 +86,3 @@
   self::use([@vm.inferred-type.metadata=#lib::X] self::returnBoxedX());
   self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnBoxedSmiFromEntryPoint());
 }
-static method use(dynamic value) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart
index 16bdbe5..f20e0ce 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart
@@ -6,6 +6,11 @@
 final bool kFalse = int.parse('1') == 2 ? true : false;
 int get mint => 0xaabbccddaabbccdd;
 int get smiOrMint => kTrue ? 1 : mint;
+dynamic usedObject;
+
+void use(dynamic object) {
+  usedObject ??= object;
+}
 
 class X {}
 
@@ -18,7 +23,16 @@
     dynamic boxedIntOrDouble,
     dynamic boxedNullableIntOrDouble,
     dynamic boxedNullableX,
-    dynamic boxedX) {}
+    dynamic boxedX) {
+  use(unboxedInt);
+  use(unboxedDouble);
+  use(boxedNullableInt);
+  use(boxedNullableDouble);
+  use(boxedIntOrDouble);
+  use(boxedNullableIntOrDouble);
+  use(boxedNullableX);
+  use(boxedX);
+}
 
 void takeOptional(
     [int unboxedSmi,
@@ -29,7 +43,16 @@
     dynamic boxedIntOrDouble,
     dynamic boxedNullableIntOrDouble,
     dynamic boxedNullableX,
-    dynamic boxedX]) {}
+    dynamic boxedX]) {
+  use(unboxedInt);
+  use(unboxedDouble);
+  use(boxedNullableInt);
+  use(boxedNullableDouble);
+  use(boxedIntOrDouble);
+  use(boxedNullableIntOrDouble);
+  use(boxedNullableX);
+  use(boxedX);
+}
 
 void takeNamed(
     {int unboxedSmi,
@@ -40,7 +63,16 @@
     dynamic boxedIntOrDouble,
     dynamic boxedNullableIntOrDouble,
     dynamic boxedNullableX,
-    dynamic boxedX}) {}
+    dynamic boxedX}) {
+  use(unboxedInt);
+  use(unboxedDouble);
+  use(boxedNullableInt);
+  use(boxedNullableDouble);
+  use(boxedIntOrDouble);
+  use(boxedNullableIntOrDouble);
+  use(boxedNullableX);
+  use(boxedX);
+}
 
 dynamic returnUnboxedSmi() => kTrue ? 1 : 2;
 dynamic returnUnboxedInt() => kTrue ? smiOrMint : 2;
@@ -99,6 +131,8 @@
 
   // Use as tear-offs.
   use(takePositional);
+  use(takeOptional);
+  use(takeNamed);
   use(returnUnboxedSmi);
   use(returnUnboxedInt);
   use(returnUnboxedDouble);
@@ -109,5 +143,3 @@
   use(returnBoxedNullableX);
   use(returnBoxedX);
 }
-
-void use(dynamic value) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
index 62e1f32..10fcb7a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method_tearoff.dart.expect
@@ -9,13 +9,44 @@
 }
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kTrue = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(1) ?{core::bool*} true : false;
 [@vm.inferred-type.metadata=dart.core::bool?]static final field core::bool* kFalse = [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1").{core::num::==}(2) ?{core::bool*} true : false;
+static field dynamic usedObject;
 [@vm.unboxing-info.metadata=()->i]static get mint() → core::int*
   return -6144092014192636707;
 [@vm.unboxing-info.metadata=()->i]static get smiOrMint() → core::int*
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : [@vm.inferred-type.metadata=int] self::mint;
-static method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {}
-static method takeOptional([@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX) → void {}
-static method takeNamed([@vm.inferred-type.metadata=!] dynamic boxedIntOrDouble, [@vm.inferred-type.metadata=dart.core::_Double?] dynamic boxedNullableDouble, [@vm.inferred-type.metadata=int?] dynamic boxedNullableInt, dynamic boxedNullableIntOrDouble, [@vm.inferred-type.metadata=#lib::X?] dynamic boxedNullableX, [@vm.inferred-type.metadata=#lib::X] dynamic boxedX, [@vm.inferred-type.metadata=dart.core::_Double] dynamic unboxedDouble, [@vm.inferred-type.metadata=int] dynamic unboxedInt, [@vm.inferred-type.metadata=dart.core::_Smi] core::int* unboxedSmi) → void {}
+static method use(dynamic object) → void {
+  [@vm.inferred-type.metadata=!? (receiver not int)] self::usedObject.{core::Object::==}(null) ?{dynamic} self::usedObject = object : null;
+}
+static method takePositional(core::int* unboxedSmi, dynamic unboxedInt, dynamic unboxedDouble, dynamic boxedNullableInt, dynamic boxedNullableDouble, dynamic boxedIntOrDouble, dynamic boxedNullableIntOrDouble, dynamic boxedNullableX, dynamic boxedX) → void {
+  self::use(unboxedInt);
+  self::use(unboxedDouble);
+  self::use(boxedNullableInt);
+  self::use(boxedNullableDouble);
+  self::use(boxedIntOrDouble);
+  self::use(boxedNullableIntOrDouble);
+  self::use(boxedNullableX);
+  self::use(boxedX);
+}
+static method takeOptional([core::int* unboxedSmi = #C1, dynamic unboxedInt = #C1, dynamic unboxedDouble = #C1, dynamic boxedNullableInt = #C1, dynamic boxedNullableDouble = #C1, dynamic boxedIntOrDouble = #C1, dynamic boxedNullableIntOrDouble = #C1, dynamic boxedNullableX = #C1, dynamic boxedX = #C1]) → void {
+  self::use(unboxedInt);
+  self::use(unboxedDouble);
+  self::use(boxedNullableInt);
+  self::use(boxedNullableDouble);
+  self::use(boxedIntOrDouble);
+  self::use(boxedNullableIntOrDouble);
+  self::use(boxedNullableX);
+  self::use(boxedX);
+}
+static method takeNamed({core::int* unboxedSmi = #C1, dynamic unboxedInt = #C1, dynamic unboxedDouble = #C1, dynamic boxedNullableInt = #C1, dynamic boxedNullableDouble = #C1, dynamic boxedIntOrDouble = #C1, dynamic boxedNullableIntOrDouble = #C1, dynamic boxedNullableX = #C1, dynamic boxedX = #C1}) → void {
+  self::use(unboxedInt);
+  self::use(unboxedDouble);
+  self::use(boxedNullableInt);
+  self::use(boxedNullableDouble);
+  self::use(boxedIntOrDouble);
+  self::use(boxedNullableIntOrDouble);
+  self::use(boxedNullableX);
+  self::use(boxedX);
+}
 [@vm.unboxing-info.metadata=()->i]static method returnUnboxedSmi() → dynamic
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
 [@vm.unboxing-info.metadata=()->i]static method returnUnboxedInt() → dynamic
@@ -37,7 +68,7 @@
 static method main() → dynamic {
   self::takePositional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
   self::takeOptional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
-  let core::int* #t1 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let core::int* #t2 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let core::double* #t3 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let core::int* #t4 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let core::double* #t5 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let core::num* #t6 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let core::num* #t7 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let self::X* #t8 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let self::X* #t9 = new self::X::•() in self::takeNamed(#t6, #t5, #t4, #t7, #t8, #t9, #t3, #t2, #t1);
+  self::takeNamed(unboxedSmi: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, unboxedInt: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, unboxedDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, boxedNullableInt: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, boxedNullableDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, boxedIntOrDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, boxedNullableIntOrDouble: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, boxedNullableX: [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, boxedX: new self::X::•());
   self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnUnboxedSmi());
   self::use([@vm.inferred-type.metadata=int] self::returnUnboxedInt());
   self::use([@vm.inferred-type.metadata=dart.core::_Double] self::returnUnboxedDouble());
@@ -47,7 +78,6 @@
   self::use(self::returnBoxedNullableIntOrDouble());
   self::use([@vm.inferred-type.metadata=#lib::X?] self::returnBoxedNullableX());
   self::use([@vm.inferred-type.metadata=#lib::X] self::returnBoxedX());
-  self::use(#C1);
   self::use(#C2);
   self::use(#C3);
   self::use(#C4);
@@ -57,5 +87,7 @@
   self::use(#C8);
   self::use(#C9);
   self::use(#C10);
+  self::use(#C11);
+  self::use(#C12);
+  self::use(#C13);
 }
-static method use(dynamic value) → void {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
index 082ed50..936781a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field2.dart.expect
@@ -12,7 +12,7 @@
     ;
 }
 class B extends core::Object {
-  constructor •([@vm.inferred-type.metadata=dart.core::_OneByteString (value: "hi")] dynamic unused4) → self::B*
+  constructor •() → self::B*
     : dynamic #t1 = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::foo(), super core::Object::•()
     ;
 }
@@ -55,7 +55,7 @@
 static method foo() → dynamic {}
 static method main() → void {
   new self::A::•();
-  new self::B::•("hi");
+  new self::B::•();
   self::C<core::num*>* c = new self::D::•();
   exp::Expect::throws<dynamic>(() → core::Null? {
     [@vm.call-site-attributes.metadata=receiverType:#lib::C<dart.core::num*>*] [@vm.direct-call.metadata=#lib::D.bar] c.{self::C::bar} = 3.14;
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 8f6992b..906eb34 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -1028,11 +1028,12 @@
     # This file must be compiled in for dynamic linking.
     "../include/dart_api_dl.c",
 
-    # The two files here do not depend on each other.
-    # flutter/flutter integration tests will only use `ffi_test_functions.cc` -
-    # any test functionality using `dart_api.h` has to go into
-    # `ffi_test_functions_vmspecific.cc`.
+    # The three files here do not depend on each other.
+    # flutter/flutter integration tests will only use
+    # `ffi_test_functions{,_generated}.cc` - any test functionality using
+    # `dart_api.h` has to go into `ffi_test_functions_vmspecific.cc`.
     "ffi_test/ffi_test_functions.cc",
+    "ffi_test/ffi_test_functions_generated.cc",
     "ffi_test/ffi_test_functions_vmspecific.cc",
   ]
   if (is_win && current_cpu == "x64") {
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index c9e39e9..3304154 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -750,12 +750,48 @@
   return retval;
 }
 
+// Can't easily share this with the generated file.
+struct Struct20BytesHomogeneousInt32Copy {
+  int32_t a0;
+  int32_t a1;
+  int32_t a2;
+  int32_t a3;
+  int32_t a4;
+};
+
+DART_EXPORT Struct20BytesHomogeneousInt32Copy PassStructRecursive(
+    int64_t recursionCounter,
+    Struct20BytesHomogeneousInt32Copy a0,
+    Struct20BytesHomogeneousInt32Copy (*f)(int64_t,
+                                           Struct20BytesHomogeneousInt32Copy)) {
+  std::cout << "PassStruct20BytesHomogeneousInt32x10"
+            << "(" << recursionCounter << ", (" << a0.a0 << ", " << a0.a1
+            << ", " << a0.a2 << ", " << a0.a3 << ", " << a0.a4 << "), "
+            << reinterpret_cast<void*>(f) << ")\n";
+  a0.a0++;
+  const int32_t a0_a0_saved = a0.a0;
+
+  if (recursionCounter <= 0) {
+    return a0;
+  }
+
+  Struct20BytesHomogeneousInt32Copy result = f(recursionCounter - 1, a0);
+  result.a0++;
+  if (a0_a0_saved != a0.a0) {
+    result.a4 = 0;
+  }
+
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Tests for callbacks.
 
 // Sanity test.
 DART_EXPORT intptr_t TestSimpleAddition(intptr_t (*add)(int, int)) {
-  CHECK_EQ(add(10, 20), 30);
+  const intptr_t result = add(10, 20);
+  std::cout << "result " << result << "\n";
+  CHECK_EQ(result, 30);
   return 0;
 }
 
@@ -764,7 +800,9 @@
 
 DART_EXPORT intptr_t
 TestIntComputation(int64_t (*fn)(int8_t, int16_t, int32_t, int64_t)) {
-  CHECK_EQ(fn(125, 250, 500, 1000), 625);
+  const int64_t result = fn(125, 250, 500, 1000);
+  std::cout << "result " << result << "\n";
+  CHECK_EQ(result, 625);
   CHECK_EQ(0x7FFFFFFFFFFFFFFFLL, fn(0, 0, 0, 0x7FFFFFFFFFFFFFFFLL));
   CHECK_EQ(((int64_t)-0x8000000000000000LL),
            fn(0, 0, 0, -0x8000000000000000LL));
diff --git a/runtime/bin/ffi_test/ffi_test_functions_generated.cc b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
new file mode 100644
index 0000000..9c9789f
--- /dev/null
+++ b/runtime/bin/ffi_test/ffi_test_functions_generated.cc
@@ -0,0 +1,8375 @@
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+#if defined(_WIN32)
+#define DART_EXPORT extern "C" __declspec(dllexport)
+#else
+#define DART_EXPORT                                                            \
+  extern "C" __attribute__((visibility("default"))) __attribute((used))
+#endif
+
+namespace dart {
+
+#define CHECK(X)                                                               \
+  if (!(X)) {                                                                  \
+    fprintf(stderr, "%s\n", "Check failed: " #X);                              \
+    return 1;                                                                  \
+  }
+
+#define CHECK_EQ(X, Y) CHECK((X) == (Y))
+
+// Works for positive, negative and zero.
+#define CHECK_APPROX(EXPECTED, ACTUAL)                                         \
+  CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) ||    \
+        ((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
+
+struct Struct0Bytes {};
+
+struct Struct1ByteInt {
+  int8_t a0;
+};
+
+struct Struct3BytesInt {
+  int16_t a0;
+  int8_t a1;
+};
+
+struct Struct4BytesHomogeneousInt16 {
+  int16_t a0;
+  int16_t a1;
+};
+
+struct Struct7BytesInt {
+  int32_t a0;
+  int16_t a1;
+  int8_t a2;
+};
+
+struct Struct8BytesInt {
+  int16_t a0;
+  int16_t a1;
+  int32_t a2;
+};
+
+struct Struct8BytesHomogeneousFloat {
+  float a0;
+  float a1;
+};
+
+struct Struct8BytesMixed {
+  float a0;
+  int16_t a1;
+  int16_t a2;
+};
+
+struct Struct9BytesInt {
+  int64_t a0;
+  int8_t a1;
+};
+
+struct Struct9BytesHomogeneousUint82 {
+  uint8_t a0;
+  uint8_t a1;
+  uint8_t a2;
+  uint8_t a3;
+  uint8_t a4;
+  uint8_t a5;
+  uint8_t a6;
+  uint8_t a7;
+  uint8_t a8;
+};
+
+struct Struct12BytesHomogeneousFloat {
+  float a0;
+  float a1;
+  float a2;
+};
+
+struct Struct16BytesHomogeneousFloat {
+  float a0;
+  float a1;
+  float a2;
+  float a3;
+};
+
+struct Struct16BytesMixed {
+  double a0;
+  int64_t a1;
+};
+
+struct Struct16BytesMixed2 {
+  float a0;
+  float a1;
+  float a2;
+  int32_t a3;
+};
+
+struct Struct17BytesInt {
+  int64_t a0;
+  int64_t a1;
+  int8_t a2;
+};
+
+struct Struct19BytesHomogeneousUint8 {
+  uint8_t a0;
+  uint8_t a1;
+  uint8_t a2;
+  uint8_t a3;
+  uint8_t a4;
+  uint8_t a5;
+  uint8_t a6;
+  uint8_t a7;
+  uint8_t a8;
+  uint8_t a9;
+  uint8_t a10;
+  uint8_t a11;
+  uint8_t a12;
+  uint8_t a13;
+  uint8_t a14;
+  uint8_t a15;
+  uint8_t a16;
+  uint8_t a17;
+  uint8_t a18;
+};
+
+struct Struct20BytesHomogeneousInt32 {
+  int32_t a0;
+  int32_t a1;
+  int32_t a2;
+  int32_t a3;
+  int32_t a4;
+};
+
+struct Struct20BytesHomogeneousFloat {
+  float a0;
+  float a1;
+  float a2;
+  float a3;
+  float a4;
+};
+
+struct Struct32BytesHomogeneousDouble {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+};
+
+struct Struct40BytesHomogeneousDouble {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+};
+
+struct Struct1024BytesHomogeneousUint64 {
+  uint64_t a0;
+  uint64_t a1;
+  uint64_t a2;
+  uint64_t a3;
+  uint64_t a4;
+  uint64_t a5;
+  uint64_t a6;
+  uint64_t a7;
+  uint64_t a8;
+  uint64_t a9;
+  uint64_t a10;
+  uint64_t a11;
+  uint64_t a12;
+  uint64_t a13;
+  uint64_t a14;
+  uint64_t a15;
+  uint64_t a16;
+  uint64_t a17;
+  uint64_t a18;
+  uint64_t a19;
+  uint64_t a20;
+  uint64_t a21;
+  uint64_t a22;
+  uint64_t a23;
+  uint64_t a24;
+  uint64_t a25;
+  uint64_t a26;
+  uint64_t a27;
+  uint64_t a28;
+  uint64_t a29;
+  uint64_t a30;
+  uint64_t a31;
+  uint64_t a32;
+  uint64_t a33;
+  uint64_t a34;
+  uint64_t a35;
+  uint64_t a36;
+  uint64_t a37;
+  uint64_t a38;
+  uint64_t a39;
+  uint64_t a40;
+  uint64_t a41;
+  uint64_t a42;
+  uint64_t a43;
+  uint64_t a44;
+  uint64_t a45;
+  uint64_t a46;
+  uint64_t a47;
+  uint64_t a48;
+  uint64_t a49;
+  uint64_t a50;
+  uint64_t a51;
+  uint64_t a52;
+  uint64_t a53;
+  uint64_t a54;
+  uint64_t a55;
+  uint64_t a56;
+  uint64_t a57;
+  uint64_t a58;
+  uint64_t a59;
+  uint64_t a60;
+  uint64_t a61;
+  uint64_t a62;
+  uint64_t a63;
+  uint64_t a64;
+  uint64_t a65;
+  uint64_t a66;
+  uint64_t a67;
+  uint64_t a68;
+  uint64_t a69;
+  uint64_t a70;
+  uint64_t a71;
+  uint64_t a72;
+  uint64_t a73;
+  uint64_t a74;
+  uint64_t a75;
+  uint64_t a76;
+  uint64_t a77;
+  uint64_t a78;
+  uint64_t a79;
+  uint64_t a80;
+  uint64_t a81;
+  uint64_t a82;
+  uint64_t a83;
+  uint64_t a84;
+  uint64_t a85;
+  uint64_t a86;
+  uint64_t a87;
+  uint64_t a88;
+  uint64_t a89;
+  uint64_t a90;
+  uint64_t a91;
+  uint64_t a92;
+  uint64_t a93;
+  uint64_t a94;
+  uint64_t a95;
+  uint64_t a96;
+  uint64_t a97;
+  uint64_t a98;
+  uint64_t a99;
+  uint64_t a100;
+  uint64_t a101;
+  uint64_t a102;
+  uint64_t a103;
+  uint64_t a104;
+  uint64_t a105;
+  uint64_t a106;
+  uint64_t a107;
+  uint64_t a108;
+  uint64_t a109;
+  uint64_t a110;
+  uint64_t a111;
+  uint64_t a112;
+  uint64_t a113;
+  uint64_t a114;
+  uint64_t a115;
+  uint64_t a116;
+  uint64_t a117;
+  uint64_t a118;
+  uint64_t a119;
+  uint64_t a120;
+  uint64_t a121;
+  uint64_t a122;
+  uint64_t a123;
+  uint64_t a124;
+  uint64_t a125;
+  uint64_t a126;
+  uint64_t a127;
+};
+
+struct StructAlignmentInt16 {
+  int8_t a0;
+  int16_t a1;
+  int8_t a2;
+};
+
+struct StructAlignmentInt32 {
+  int8_t a0;
+  int32_t a1;
+  int8_t a2;
+};
+
+struct StructAlignmentInt64 {
+  int8_t a0;
+  int64_t a1;
+  int8_t a2;
+};
+
+// Used for testing structs by value.
+// Smallest struct with data.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT int64_t PassStruct1ByteIntx10(Struct1ByteInt a0,
+                                          Struct1ByteInt a1,
+                                          Struct1ByteInt a2,
+                                          Struct1ByteInt a3,
+                                          Struct1ByteInt a4,
+                                          Struct1ByteInt a5,
+                                          Struct1ByteInt a6,
+                                          Struct1ByteInt a7,
+                                          Struct1ByteInt a8,
+                                          Struct1ByteInt a9) {
+  std::cout << "PassStruct1ByteIntx10"
+            << "((" << static_cast<int>(a0.a0) << "), ("
+            << static_cast<int>(a1.a0) << "), (" << static_cast<int>(a2.a0)
+            << "), (" << static_cast<int>(a3.a0) << "), ("
+            << static_cast<int>(a4.a0) << "), (" << static_cast<int>(a5.a0)
+            << "), (" << static_cast<int>(a6.a0) << "), ("
+            << static_cast<int>(a7.a0) << "), (" << static_cast<int>(a8.a0)
+            << "), (" << static_cast<int>(a9.a0) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a1.a0;
+  result += a2.a0;
+  result += a3.a0;
+  result += a4.a0;
+  result += a5.a0;
+  result += a6.a0;
+  result += a7.a0;
+  result += a8.a0;
+  result += a9.a0;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Not a multiple of word size, not a power of two.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT int64_t PassStruct3BytesIntx10(Struct3BytesInt a0,
+                                           Struct3BytesInt a1,
+                                           Struct3BytesInt a2,
+                                           Struct3BytesInt a3,
+                                           Struct3BytesInt a4,
+                                           Struct3BytesInt a5,
+                                           Struct3BytesInt a6,
+                                           Struct3BytesInt a7,
+                                           Struct3BytesInt a8,
+                                           Struct3BytesInt a9) {
+  std::cout << "PassStruct3BytesIntx10"
+            << "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
+            << a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
+            << ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
+            << static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
+            << static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
+            << static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
+            << static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
+            << static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
+            << static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
+            << static_cast<int>(a9.a1) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Exactly word size on 32-bit architectures.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT int64_t
+PassStruct4BytesHomogeneousInt16x10(Struct4BytesHomogeneousInt16 a0,
+                                    Struct4BytesHomogeneousInt16 a1,
+                                    Struct4BytesHomogeneousInt16 a2,
+                                    Struct4BytesHomogeneousInt16 a3,
+                                    Struct4BytesHomogeneousInt16 a4,
+                                    Struct4BytesHomogeneousInt16 a5,
+                                    Struct4BytesHomogeneousInt16 a6,
+                                    Struct4BytesHomogeneousInt16 a7,
+                                    Struct4BytesHomogeneousInt16 a8,
+                                    Struct4BytesHomogeneousInt16 a9) {
+  std::cout << "PassStruct4BytesHomogeneousInt16x10"
+            << "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
+            << a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
+            << ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
+            << a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
+            << "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
+            << a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Sub word size on 64 bit architectures.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT int64_t PassStruct7BytesIntx10(Struct7BytesInt a0,
+                                           Struct7BytesInt a1,
+                                           Struct7BytesInt a2,
+                                           Struct7BytesInt a3,
+                                           Struct7BytesInt a4,
+                                           Struct7BytesInt a5,
+                                           Struct7BytesInt a6,
+                                           Struct7BytesInt a7,
+                                           Struct7BytesInt a8,
+                                           Struct7BytesInt a9) {
+  std::cout << "PassStruct7BytesIntx10"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
+            << "), (" << a1.a0 << ", " << a1.a1 << ", "
+            << static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
+            << ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
+            << ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
+            << a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
+            << "), (" << a6.a0 << ", " << a6.a1 << ", "
+            << static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
+            << ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
+            << a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Exactly word size struct on 64bit architectures.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT int64_t PassStruct8BytesIntx10(Struct8BytesInt a0,
+                                           Struct8BytesInt a1,
+                                           Struct8BytesInt a2,
+                                           Struct8BytesInt a3,
+                                           Struct8BytesInt a4,
+                                           Struct8BytesInt a5,
+                                           Struct8BytesInt a6,
+                                           Struct8BytesInt a7,
+                                           Struct8BytesInt a8,
+                                           Struct8BytesInt a9) {
+  std::cout << "PassStruct8BytesIntx10"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
+            << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
+            << a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
+            << "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
+            << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << a9.a2 << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Arguments passed in FP registers as long as they fit.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT float PassStruct8BytesHomogeneousFloatx10(
+    Struct8BytesHomogeneousFloat a0,
+    Struct8BytesHomogeneousFloat a1,
+    Struct8BytesHomogeneousFloat a2,
+    Struct8BytesHomogeneousFloat a3,
+    Struct8BytesHomogeneousFloat a4,
+    Struct8BytesHomogeneousFloat a5,
+    Struct8BytesHomogeneousFloat a6,
+    Struct8BytesHomogeneousFloat a7,
+    Struct8BytesHomogeneousFloat a8,
+    Struct8BytesHomogeneousFloat a9) {
+  std::cout << "PassStruct8BytesHomogeneousFloatx10"
+            << "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
+            << a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
+            << ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
+            << a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
+            << "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
+            << a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
+            << "\n";
+
+  float result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On x64, arguments go in int registers because it is not only float.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT float PassStruct8BytesMixedx10(Struct8BytesMixed a0,
+                                           Struct8BytesMixed a1,
+                                           Struct8BytesMixed a2,
+                                           Struct8BytesMixed a3,
+                                           Struct8BytesMixed a4,
+                                           Struct8BytesMixed a5,
+                                           Struct8BytesMixed a6,
+                                           Struct8BytesMixed a7,
+                                           Struct8BytesMixed a8,
+                                           Struct8BytesMixed a9) {
+  std::cout << "PassStruct8BytesMixedx10"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
+            << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
+            << a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
+            << "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
+            << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << a9.a2 << "))"
+            << "\n";
+
+  float result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Argument is a single byte over a multiple of word size.
+// 10 struct arguments will exhaust available registers.
+// Tests upper bytes in the integer registers that are partly filled.
+// Tests stack alignment of non word size stack arguments.
+DART_EXPORT int64_t PassStruct9BytesIntx10(Struct9BytesInt a0,
+                                           Struct9BytesInt a1,
+                                           Struct9BytesInt a2,
+                                           Struct9BytesInt a3,
+                                           Struct9BytesInt a4,
+                                           Struct9BytesInt a5,
+                                           Struct9BytesInt a6,
+                                           Struct9BytesInt a7,
+                                           Struct9BytesInt a8,
+                                           Struct9BytesInt a9) {
+  std::cout << "PassStruct9BytesIntx10"
+            << "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
+            << a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
+            << ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
+            << static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
+            << static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
+            << static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
+            << static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
+            << static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
+            << static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
+            << static_cast<int>(a9.a1) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Argument is a single byte over a multiple of word size.
+// 10 struct arguments will exhaust available registers.
+// Struct only has 1-byte aligned fields to test struct alignment itself.
+//
+DART_EXPORT int64_t
+PassStruct9BytesHomogeneousUint82x10(Struct9BytesHomogeneousUint82 a0,
+                                     Struct9BytesHomogeneousUint82 a1,
+                                     Struct9BytesHomogeneousUint82 a2,
+                                     Struct9BytesHomogeneousUint82 a3,
+                                     Struct9BytesHomogeneousUint82 a4,
+                                     Struct9BytesHomogeneousUint82 a5,
+                                     Struct9BytesHomogeneousUint82 a6,
+                                     Struct9BytesHomogeneousUint82 a7,
+                                     Struct9BytesHomogeneousUint82 a8,
+                                     Struct9BytesHomogeneousUint82 a9) {
+  std::cout
+      << "PassStruct9BytesHomogeneousUint82x10"
+      << "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
+      << ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
+      << ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
+      << ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
+      << ", " << static_cast<int>(a0.a8) << "), (" << static_cast<int>(a1.a0)
+      << ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
+      << ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
+      << ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
+      << ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
+      << "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
+      << ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
+      << ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
+      << ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
+      << ", " << static_cast<int>(a2.a8) << "), (" << static_cast<int>(a3.a0)
+      << ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
+      << ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
+      << ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
+      << ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
+      << "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
+      << ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
+      << ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
+      << ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
+      << ", " << static_cast<int>(a4.a8) << "), (" << static_cast<int>(a5.a0)
+      << ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
+      << ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
+      << ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
+      << ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
+      << "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
+      << ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
+      << ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
+      << ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
+      << ", " << static_cast<int>(a6.a8) << "), (" << static_cast<int>(a7.a0)
+      << ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
+      << ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
+      << ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
+      << ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
+      << "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
+      << ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
+      << ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
+      << ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
+      << ", " << static_cast<int>(a8.a8) << "), (" << static_cast<int>(a9.a0)
+      << ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
+      << ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
+      << ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
+      << ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
+      << "))"
+      << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+  result += a0.a5;
+  result += a0.a6;
+  result += a0.a7;
+  result += a0.a8;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a1.a4;
+  result += a1.a5;
+  result += a1.a6;
+  result += a1.a7;
+  result += a1.a8;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a2.a4;
+  result += a2.a5;
+  result += a2.a6;
+  result += a2.a7;
+  result += a2.a8;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a3.a4;
+  result += a3.a5;
+  result += a3.a6;
+  result += a3.a7;
+  result += a3.a8;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+  result += a4.a4;
+  result += a4.a5;
+  result += a4.a6;
+  result += a4.a7;
+  result += a4.a8;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a5.a4;
+  result += a5.a5;
+  result += a5.a6;
+  result += a5.a7;
+  result += a5.a8;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a6.a3;
+  result += a6.a4;
+  result += a6.a5;
+  result += a6.a6;
+  result += a6.a7;
+  result += a6.a8;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a7.a4;
+  result += a7.a5;
+  result += a7.a6;
+  result += a7.a7;
+  result += a7.a8;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a8.a3;
+  result += a8.a4;
+  result += a8.a5;
+  result += a8.a6;
+  result += a8.a7;
+  result += a8.a8;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+  result += a9.a3;
+  result += a9.a4;
+  result += a9.a5;
+  result += a9.a6;
+  result += a9.a7;
+  result += a9.a8;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Arguments in FPU registers on arm hardfp and arm64.
+// Struct arguments will exhaust available registers, and leave some empty.
+// The last argument is to test whether arguments are backfilled.
+DART_EXPORT float PassStruct12BytesHomogeneousFloatx6(
+    Struct12BytesHomogeneousFloat a0,
+    Struct12BytesHomogeneousFloat a1,
+    Struct12BytesHomogeneousFloat a2,
+    Struct12BytesHomogeneousFloat a3,
+    Struct12BytesHomogeneousFloat a4,
+    Struct12BytesHomogeneousFloat a5) {
+  std::cout << "PassStruct12BytesHomogeneousFloatx6"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
+            << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
+            << a5.a2 << "))"
+            << "\n";
+
+  float result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On Linux x64 argument is transferred on stack because it is over 16 bytes.
+// Arguments in FPU registers on arm hardfp and arm64.
+// 5 struct arguments will exhaust available registers.
+DART_EXPORT float PassStruct16BytesHomogeneousFloatx5(
+    Struct16BytesHomogeneousFloat a0,
+    Struct16BytesHomogeneousFloat a1,
+    Struct16BytesHomogeneousFloat a2,
+    Struct16BytesHomogeneousFloat a3,
+    Struct16BytesHomogeneousFloat a4) {
+  std::cout << "PassStruct16BytesHomogeneousFloatx5"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
+            << a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
+            << ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
+            << a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << "))"
+            << "\n";
+
+  float result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On x64, arguments are split over FP and int registers.
+// On x64, it will exhaust the integer registers with the 6th argument.
+// The rest goes on the stack.
+// On arm, arguments are 8 byte aligned.
+DART_EXPORT double PassStruct16BytesMixedx10(Struct16BytesMixed a0,
+                                             Struct16BytesMixed a1,
+                                             Struct16BytesMixed a2,
+                                             Struct16BytesMixed a3,
+                                             Struct16BytesMixed a4,
+                                             Struct16BytesMixed a5,
+                                             Struct16BytesMixed a6,
+                                             Struct16BytesMixed a7,
+                                             Struct16BytesMixed a8,
+                                             Struct16BytesMixed a9) {
+  std::cout << "PassStruct16BytesMixedx10"
+            << "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
+            << a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
+            << ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
+            << a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
+            << "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
+            << a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On x64, arguments are split over FP and int registers.
+// On x64, it will exhaust the integer registers with the 6th argument.
+// The rest goes on the stack.
+// On arm, arguments are 4 byte aligned.
+DART_EXPORT float PassStruct16BytesMixed2x10(Struct16BytesMixed2 a0,
+                                             Struct16BytesMixed2 a1,
+                                             Struct16BytesMixed2 a2,
+                                             Struct16BytesMixed2 a3,
+                                             Struct16BytesMixed2 a4,
+                                             Struct16BytesMixed2 a5,
+                                             Struct16BytesMixed2 a6,
+                                             Struct16BytesMixed2 a7,
+                                             Struct16BytesMixed2 a8,
+                                             Struct16BytesMixed2 a9) {
+  std::cout << "PassStruct16BytesMixed2x10"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
+            << a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
+            << ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
+            << a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << "), (" << a5.a0 << ", "
+            << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), (" << a6.a0
+            << ", " << a6.a1 << ", " << a6.a2 << ", " << a6.a3 << "), ("
+            << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
+            << "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
+            << a8.a3 << "), (" << a9.a0 << ", " << a9.a1 << ", " << a9.a2
+            << ", " << a9.a3 << "))"
+            << "\n";
+
+  float result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a6.a3;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a8.a3;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+  result += a9.a3;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Arguments are passed as pointer to copy on arm64.
+// Tests that the memory allocated for copies are rounded up to word size.
+DART_EXPORT int64_t PassStruct17BytesIntx10(Struct17BytesInt a0,
+                                            Struct17BytesInt a1,
+                                            Struct17BytesInt a2,
+                                            Struct17BytesInt a3,
+                                            Struct17BytesInt a4,
+                                            Struct17BytesInt a5,
+                                            Struct17BytesInt a6,
+                                            Struct17BytesInt a7,
+                                            Struct17BytesInt a8,
+                                            Struct17BytesInt a9) {
+  std::cout << "PassStruct17BytesIntx10"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
+            << "), (" << a1.a0 << ", " << a1.a1 << ", "
+            << static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
+            << ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
+            << ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
+            << a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
+            << "), (" << a6.a0 << ", " << a6.a1 << ", "
+            << static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
+            << ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
+            << a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// The minimum alignment of this struct is only 1 byte based on its fields.
+// Test that the memory backing these structs is extended to the right size.
+//
+DART_EXPORT int64_t
+PassStruct19BytesHomogeneousUint8x10(Struct19BytesHomogeneousUint8 a0,
+                                     Struct19BytesHomogeneousUint8 a1,
+                                     Struct19BytesHomogeneousUint8 a2,
+                                     Struct19BytesHomogeneousUint8 a3,
+                                     Struct19BytesHomogeneousUint8 a4,
+                                     Struct19BytesHomogeneousUint8 a5,
+                                     Struct19BytesHomogeneousUint8 a6,
+                                     Struct19BytesHomogeneousUint8 a7,
+                                     Struct19BytesHomogeneousUint8 a8,
+                                     Struct19BytesHomogeneousUint8 a9) {
+  std::cout
+      << "PassStruct19BytesHomogeneousUint8x10"
+      << "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
+      << ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
+      << ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
+      << ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
+      << ", " << static_cast<int>(a0.a8) << ", " << static_cast<int>(a0.a9)
+      << ", " << static_cast<int>(a0.a10) << ", " << static_cast<int>(a0.a11)
+      << ", " << static_cast<int>(a0.a12) << ", " << static_cast<int>(a0.a13)
+      << ", " << static_cast<int>(a0.a14) << ", " << static_cast<int>(a0.a15)
+      << ", " << static_cast<int>(a0.a16) << ", " << static_cast<int>(a0.a17)
+      << ", " << static_cast<int>(a0.a18) << "), (" << static_cast<int>(a1.a0)
+      << ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
+      << ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
+      << ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
+      << ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
+      << ", " << static_cast<int>(a1.a9) << ", " << static_cast<int>(a1.a10)
+      << ", " << static_cast<int>(a1.a11) << ", " << static_cast<int>(a1.a12)
+      << ", " << static_cast<int>(a1.a13) << ", " << static_cast<int>(a1.a14)
+      << ", " << static_cast<int>(a1.a15) << ", " << static_cast<int>(a1.a16)
+      << ", " << static_cast<int>(a1.a17) << ", " << static_cast<int>(a1.a18)
+      << "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
+      << ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
+      << ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
+      << ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
+      << ", " << static_cast<int>(a2.a8) << ", " << static_cast<int>(a2.a9)
+      << ", " << static_cast<int>(a2.a10) << ", " << static_cast<int>(a2.a11)
+      << ", " << static_cast<int>(a2.a12) << ", " << static_cast<int>(a2.a13)
+      << ", " << static_cast<int>(a2.a14) << ", " << static_cast<int>(a2.a15)
+      << ", " << static_cast<int>(a2.a16) << ", " << static_cast<int>(a2.a17)
+      << ", " << static_cast<int>(a2.a18) << "), (" << static_cast<int>(a3.a0)
+      << ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
+      << ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
+      << ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
+      << ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
+      << ", " << static_cast<int>(a3.a9) << ", " << static_cast<int>(a3.a10)
+      << ", " << static_cast<int>(a3.a11) << ", " << static_cast<int>(a3.a12)
+      << ", " << static_cast<int>(a3.a13) << ", " << static_cast<int>(a3.a14)
+      << ", " << static_cast<int>(a3.a15) << ", " << static_cast<int>(a3.a16)
+      << ", " << static_cast<int>(a3.a17) << ", " << static_cast<int>(a3.a18)
+      << "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
+      << ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
+      << ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
+      << ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
+      << ", " << static_cast<int>(a4.a8) << ", " << static_cast<int>(a4.a9)
+      << ", " << static_cast<int>(a4.a10) << ", " << static_cast<int>(a4.a11)
+      << ", " << static_cast<int>(a4.a12) << ", " << static_cast<int>(a4.a13)
+      << ", " << static_cast<int>(a4.a14) << ", " << static_cast<int>(a4.a15)
+      << ", " << static_cast<int>(a4.a16) << ", " << static_cast<int>(a4.a17)
+      << ", " << static_cast<int>(a4.a18) << "), (" << static_cast<int>(a5.a0)
+      << ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
+      << ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
+      << ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
+      << ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
+      << ", " << static_cast<int>(a5.a9) << ", " << static_cast<int>(a5.a10)
+      << ", " << static_cast<int>(a5.a11) << ", " << static_cast<int>(a5.a12)
+      << ", " << static_cast<int>(a5.a13) << ", " << static_cast<int>(a5.a14)
+      << ", " << static_cast<int>(a5.a15) << ", " << static_cast<int>(a5.a16)
+      << ", " << static_cast<int>(a5.a17) << ", " << static_cast<int>(a5.a18)
+      << "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
+      << ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
+      << ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
+      << ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
+      << ", " << static_cast<int>(a6.a8) << ", " << static_cast<int>(a6.a9)
+      << ", " << static_cast<int>(a6.a10) << ", " << static_cast<int>(a6.a11)
+      << ", " << static_cast<int>(a6.a12) << ", " << static_cast<int>(a6.a13)
+      << ", " << static_cast<int>(a6.a14) << ", " << static_cast<int>(a6.a15)
+      << ", " << static_cast<int>(a6.a16) << ", " << static_cast<int>(a6.a17)
+      << ", " << static_cast<int>(a6.a18) << "), (" << static_cast<int>(a7.a0)
+      << ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
+      << ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
+      << ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
+      << ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
+      << ", " << static_cast<int>(a7.a9) << ", " << static_cast<int>(a7.a10)
+      << ", " << static_cast<int>(a7.a11) << ", " << static_cast<int>(a7.a12)
+      << ", " << static_cast<int>(a7.a13) << ", " << static_cast<int>(a7.a14)
+      << ", " << static_cast<int>(a7.a15) << ", " << static_cast<int>(a7.a16)
+      << ", " << static_cast<int>(a7.a17) << ", " << static_cast<int>(a7.a18)
+      << "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
+      << ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
+      << ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
+      << ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
+      << ", " << static_cast<int>(a8.a8) << ", " << static_cast<int>(a8.a9)
+      << ", " << static_cast<int>(a8.a10) << ", " << static_cast<int>(a8.a11)
+      << ", " << static_cast<int>(a8.a12) << ", " << static_cast<int>(a8.a13)
+      << ", " << static_cast<int>(a8.a14) << ", " << static_cast<int>(a8.a15)
+      << ", " << static_cast<int>(a8.a16) << ", " << static_cast<int>(a8.a17)
+      << ", " << static_cast<int>(a8.a18) << "), (" << static_cast<int>(a9.a0)
+      << ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
+      << ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
+      << ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
+      << ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
+      << ", " << static_cast<int>(a9.a9) << ", " << static_cast<int>(a9.a10)
+      << ", " << static_cast<int>(a9.a11) << ", " << static_cast<int>(a9.a12)
+      << ", " << static_cast<int>(a9.a13) << ", " << static_cast<int>(a9.a14)
+      << ", " << static_cast<int>(a9.a15) << ", " << static_cast<int>(a9.a16)
+      << ", " << static_cast<int>(a9.a17) << ", " << static_cast<int>(a9.a18)
+      << "))"
+      << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+  result += a0.a5;
+  result += a0.a6;
+  result += a0.a7;
+  result += a0.a8;
+  result += a0.a9;
+  result += a0.a10;
+  result += a0.a11;
+  result += a0.a12;
+  result += a0.a13;
+  result += a0.a14;
+  result += a0.a15;
+  result += a0.a16;
+  result += a0.a17;
+  result += a0.a18;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a1.a4;
+  result += a1.a5;
+  result += a1.a6;
+  result += a1.a7;
+  result += a1.a8;
+  result += a1.a9;
+  result += a1.a10;
+  result += a1.a11;
+  result += a1.a12;
+  result += a1.a13;
+  result += a1.a14;
+  result += a1.a15;
+  result += a1.a16;
+  result += a1.a17;
+  result += a1.a18;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a2.a4;
+  result += a2.a5;
+  result += a2.a6;
+  result += a2.a7;
+  result += a2.a8;
+  result += a2.a9;
+  result += a2.a10;
+  result += a2.a11;
+  result += a2.a12;
+  result += a2.a13;
+  result += a2.a14;
+  result += a2.a15;
+  result += a2.a16;
+  result += a2.a17;
+  result += a2.a18;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a3.a4;
+  result += a3.a5;
+  result += a3.a6;
+  result += a3.a7;
+  result += a3.a8;
+  result += a3.a9;
+  result += a3.a10;
+  result += a3.a11;
+  result += a3.a12;
+  result += a3.a13;
+  result += a3.a14;
+  result += a3.a15;
+  result += a3.a16;
+  result += a3.a17;
+  result += a3.a18;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+  result += a4.a4;
+  result += a4.a5;
+  result += a4.a6;
+  result += a4.a7;
+  result += a4.a8;
+  result += a4.a9;
+  result += a4.a10;
+  result += a4.a11;
+  result += a4.a12;
+  result += a4.a13;
+  result += a4.a14;
+  result += a4.a15;
+  result += a4.a16;
+  result += a4.a17;
+  result += a4.a18;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a5.a4;
+  result += a5.a5;
+  result += a5.a6;
+  result += a5.a7;
+  result += a5.a8;
+  result += a5.a9;
+  result += a5.a10;
+  result += a5.a11;
+  result += a5.a12;
+  result += a5.a13;
+  result += a5.a14;
+  result += a5.a15;
+  result += a5.a16;
+  result += a5.a17;
+  result += a5.a18;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a6.a3;
+  result += a6.a4;
+  result += a6.a5;
+  result += a6.a6;
+  result += a6.a7;
+  result += a6.a8;
+  result += a6.a9;
+  result += a6.a10;
+  result += a6.a11;
+  result += a6.a12;
+  result += a6.a13;
+  result += a6.a14;
+  result += a6.a15;
+  result += a6.a16;
+  result += a6.a17;
+  result += a6.a18;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a7.a4;
+  result += a7.a5;
+  result += a7.a6;
+  result += a7.a7;
+  result += a7.a8;
+  result += a7.a9;
+  result += a7.a10;
+  result += a7.a11;
+  result += a7.a12;
+  result += a7.a13;
+  result += a7.a14;
+  result += a7.a15;
+  result += a7.a16;
+  result += a7.a17;
+  result += a7.a18;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a8.a3;
+  result += a8.a4;
+  result += a8.a5;
+  result += a8.a6;
+  result += a8.a7;
+  result += a8.a8;
+  result += a8.a9;
+  result += a8.a10;
+  result += a8.a11;
+  result += a8.a12;
+  result += a8.a13;
+  result += a8.a14;
+  result += a8.a15;
+  result += a8.a16;
+  result += a8.a17;
+  result += a8.a18;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+  result += a9.a3;
+  result += a9.a4;
+  result += a9.a5;
+  result += a9.a6;
+  result += a9.a7;
+  result += a9.a8;
+  result += a9.a9;
+  result += a9.a10;
+  result += a9.a11;
+  result += a9.a12;
+  result += a9.a13;
+  result += a9.a14;
+  result += a9.a15;
+  result += a9.a16;
+  result += a9.a17;
+  result += a9.a18;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Argument too big to go into integer registers on arm64.
+// The arguments are passed as pointers to copies.
+// The amount of arguments exhausts the number of integer registers, such that
+// pointers to copies are also passed on the stack.
+DART_EXPORT int32_t
+PassStruct20BytesHomogeneousInt32x10(Struct20BytesHomogeneousInt32 a0,
+                                     Struct20BytesHomogeneousInt32 a1,
+                                     Struct20BytesHomogeneousInt32 a2,
+                                     Struct20BytesHomogeneousInt32 a3,
+                                     Struct20BytesHomogeneousInt32 a4,
+                                     Struct20BytesHomogeneousInt32 a5,
+                                     Struct20BytesHomogeneousInt32 a6,
+                                     Struct20BytesHomogeneousInt32 a7,
+                                     Struct20BytesHomogeneousInt32 a8,
+                                     Struct20BytesHomogeneousInt32 a9) {
+  std::cout << "PassStruct20BytesHomogeneousInt32x10"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << ", "
+            << a1.a2 << ", " << a1.a3 << ", " << a1.a4 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << ", " << a2.a3 << ", " << a2.a4
+            << "), (" << a3.a0 << ", " << a3.a1 << ", " << a3.a2 << ", "
+            << a3.a3 << ", " << a3.a4 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << ", " << a4.a4 << "), ("
+            << a5.a0 << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << ", "
+            << a5.a4 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
+            << ", " << a6.a3 << ", " << a6.a4 << "), (" << a7.a0 << ", "
+            << a7.a1 << ", " << a7.a2 << ", " << a7.a3 << ", " << a7.a4
+            << "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
+            << a8.a3 << ", " << a8.a4 << "), (" << a9.a0 << ", " << a9.a1
+            << ", " << a9.a2 << ", " << a9.a3 << ", " << a9.a4 << "))"
+            << "\n";
+
+  int32_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a1.a4;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a2.a4;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a3.a4;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+  result += a4.a4;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a5.a4;
+  result += a6.a0;
+  result += a6.a1;
+  result += a6.a2;
+  result += a6.a3;
+  result += a6.a4;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a7.a4;
+  result += a8.a0;
+  result += a8.a1;
+  result += a8.a2;
+  result += a8.a3;
+  result += a8.a4;
+  result += a9.a0;
+  result += a9.a1;
+  result += a9.a2;
+  result += a9.a3;
+  result += a9.a4;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Argument too big to go into FPU registers in hardfp and arm64.
+DART_EXPORT float PassStruct20BytesHomogeneousFloat(
+    Struct20BytesHomogeneousFloat a0) {
+  std::cout << "PassStruct20BytesHomogeneousFloat"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "))"
+            << "\n";
+
+  float result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Arguments in FPU registers on arm64.
+// 5 struct arguments will exhaust available registers.
+DART_EXPORT double PassStruct32BytesHomogeneousDoublex5(
+    Struct32BytesHomogeneousDouble a0,
+    Struct32BytesHomogeneousDouble a1,
+    Struct32BytesHomogeneousDouble a2,
+    Struct32BytesHomogeneousDouble a3,
+    Struct32BytesHomogeneousDouble a4) {
+  std::cout << "PassStruct32BytesHomogeneousDoublex5"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
+            << a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
+            << ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
+            << a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << "))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a2.a0;
+  result += a2.a1;
+  result += a2.a2;
+  result += a2.a3;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a4.a0;
+  result += a4.a1;
+  result += a4.a2;
+  result += a4.a3;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Argument too big to go into FPU registers in arm64.
+DART_EXPORT double PassStruct40BytesHomogeneousDouble(
+    Struct40BytesHomogeneousDouble a0) {
+  std::cout << "PassStruct40BytesHomogeneousDouble"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test 1kb struct.
+DART_EXPORT uint64_t
+PassStruct1024BytesHomogeneousUint64(Struct1024BytesHomogeneousUint64 a0) {
+  std::cout << "PassStruct1024BytesHomogeneousUint64"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << ", " << a0.a5 << ", " << a0.a6 << ", " << a0.a7
+            << ", " << a0.a8 << ", " << a0.a9 << ", " << a0.a10 << ", "
+            << a0.a11 << ", " << a0.a12 << ", " << a0.a13 << ", " << a0.a14
+            << ", " << a0.a15 << ", " << a0.a16 << ", " << a0.a17 << ", "
+            << a0.a18 << ", " << a0.a19 << ", " << a0.a20 << ", " << a0.a21
+            << ", " << a0.a22 << ", " << a0.a23 << ", " << a0.a24 << ", "
+            << a0.a25 << ", " << a0.a26 << ", " << a0.a27 << ", " << a0.a28
+            << ", " << a0.a29 << ", " << a0.a30 << ", " << a0.a31 << ", "
+            << a0.a32 << ", " << a0.a33 << ", " << a0.a34 << ", " << a0.a35
+            << ", " << a0.a36 << ", " << a0.a37 << ", " << a0.a38 << ", "
+            << a0.a39 << ", " << a0.a40 << ", " << a0.a41 << ", " << a0.a42
+            << ", " << a0.a43 << ", " << a0.a44 << ", " << a0.a45 << ", "
+            << a0.a46 << ", " << a0.a47 << ", " << a0.a48 << ", " << a0.a49
+            << ", " << a0.a50 << ", " << a0.a51 << ", " << a0.a52 << ", "
+            << a0.a53 << ", " << a0.a54 << ", " << a0.a55 << ", " << a0.a56
+            << ", " << a0.a57 << ", " << a0.a58 << ", " << a0.a59 << ", "
+            << a0.a60 << ", " << a0.a61 << ", " << a0.a62 << ", " << a0.a63
+            << ", " << a0.a64 << ", " << a0.a65 << ", " << a0.a66 << ", "
+            << a0.a67 << ", " << a0.a68 << ", " << a0.a69 << ", " << a0.a70
+            << ", " << a0.a71 << ", " << a0.a72 << ", " << a0.a73 << ", "
+            << a0.a74 << ", " << a0.a75 << ", " << a0.a76 << ", " << a0.a77
+            << ", " << a0.a78 << ", " << a0.a79 << ", " << a0.a80 << ", "
+            << a0.a81 << ", " << a0.a82 << ", " << a0.a83 << ", " << a0.a84
+            << ", " << a0.a85 << ", " << a0.a86 << ", " << a0.a87 << ", "
+            << a0.a88 << ", " << a0.a89 << ", " << a0.a90 << ", " << a0.a91
+            << ", " << a0.a92 << ", " << a0.a93 << ", " << a0.a94 << ", "
+            << a0.a95 << ", " << a0.a96 << ", " << a0.a97 << ", " << a0.a98
+            << ", " << a0.a99 << ", " << a0.a100 << ", " << a0.a101 << ", "
+            << a0.a102 << ", " << a0.a103 << ", " << a0.a104 << ", " << a0.a105
+            << ", " << a0.a106 << ", " << a0.a107 << ", " << a0.a108 << ", "
+            << a0.a109 << ", " << a0.a110 << ", " << a0.a111 << ", " << a0.a112
+            << ", " << a0.a113 << ", " << a0.a114 << ", " << a0.a115 << ", "
+            << a0.a116 << ", " << a0.a117 << ", " << a0.a118 << ", " << a0.a119
+            << ", " << a0.a120 << ", " << a0.a121 << ", " << a0.a122 << ", "
+            << a0.a123 << ", " << a0.a124 << ", " << a0.a125 << ", " << a0.a126
+            << ", " << a0.a127 << "))"
+            << "\n";
+
+  uint64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+  result += a0.a5;
+  result += a0.a6;
+  result += a0.a7;
+  result += a0.a8;
+  result += a0.a9;
+  result += a0.a10;
+  result += a0.a11;
+  result += a0.a12;
+  result += a0.a13;
+  result += a0.a14;
+  result += a0.a15;
+  result += a0.a16;
+  result += a0.a17;
+  result += a0.a18;
+  result += a0.a19;
+  result += a0.a20;
+  result += a0.a21;
+  result += a0.a22;
+  result += a0.a23;
+  result += a0.a24;
+  result += a0.a25;
+  result += a0.a26;
+  result += a0.a27;
+  result += a0.a28;
+  result += a0.a29;
+  result += a0.a30;
+  result += a0.a31;
+  result += a0.a32;
+  result += a0.a33;
+  result += a0.a34;
+  result += a0.a35;
+  result += a0.a36;
+  result += a0.a37;
+  result += a0.a38;
+  result += a0.a39;
+  result += a0.a40;
+  result += a0.a41;
+  result += a0.a42;
+  result += a0.a43;
+  result += a0.a44;
+  result += a0.a45;
+  result += a0.a46;
+  result += a0.a47;
+  result += a0.a48;
+  result += a0.a49;
+  result += a0.a50;
+  result += a0.a51;
+  result += a0.a52;
+  result += a0.a53;
+  result += a0.a54;
+  result += a0.a55;
+  result += a0.a56;
+  result += a0.a57;
+  result += a0.a58;
+  result += a0.a59;
+  result += a0.a60;
+  result += a0.a61;
+  result += a0.a62;
+  result += a0.a63;
+  result += a0.a64;
+  result += a0.a65;
+  result += a0.a66;
+  result += a0.a67;
+  result += a0.a68;
+  result += a0.a69;
+  result += a0.a70;
+  result += a0.a71;
+  result += a0.a72;
+  result += a0.a73;
+  result += a0.a74;
+  result += a0.a75;
+  result += a0.a76;
+  result += a0.a77;
+  result += a0.a78;
+  result += a0.a79;
+  result += a0.a80;
+  result += a0.a81;
+  result += a0.a82;
+  result += a0.a83;
+  result += a0.a84;
+  result += a0.a85;
+  result += a0.a86;
+  result += a0.a87;
+  result += a0.a88;
+  result += a0.a89;
+  result += a0.a90;
+  result += a0.a91;
+  result += a0.a92;
+  result += a0.a93;
+  result += a0.a94;
+  result += a0.a95;
+  result += a0.a96;
+  result += a0.a97;
+  result += a0.a98;
+  result += a0.a99;
+  result += a0.a100;
+  result += a0.a101;
+  result += a0.a102;
+  result += a0.a103;
+  result += a0.a104;
+  result += a0.a105;
+  result += a0.a106;
+  result += a0.a107;
+  result += a0.a108;
+  result += a0.a109;
+  result += a0.a110;
+  result += a0.a111;
+  result += a0.a112;
+  result += a0.a113;
+  result += a0.a114;
+  result += a0.a115;
+  result += a0.a116;
+  result += a0.a117;
+  result += a0.a118;
+  result += a0.a119;
+  result += a0.a120;
+  result += a0.a121;
+  result += a0.a122;
+  result += a0.a123;
+  result += a0.a124;
+  result += a0.a125;
+  result += a0.a126;
+  result += a0.a127;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Tests the alignment of structs in FPU registers and backfilling.
+DART_EXPORT float PassFloatStruct16BytesHomogeneousFloatFloatStruct1(
+    float a0,
+    Struct16BytesHomogeneousFloat a1,
+    float a2,
+    Struct16BytesHomogeneousFloat a3,
+    float a4,
+    Struct16BytesHomogeneousFloat a5,
+    float a6,
+    Struct16BytesHomogeneousFloat a7,
+    float a8) {
+  std::cout << "PassFloatStruct16BytesHomogeneousFloatFloatStruct1"
+            << "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
+            << ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
+            << ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
+            << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
+            << ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
+            << "), " << a8 << ")"
+            << "\n";
+
+  float result = 0;
+
+  result += a0;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a4;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a6;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a8;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Tests the alignment of structs in FPU registers and backfilling.
+DART_EXPORT double PassFloatStruct32BytesHomogeneousDoubleFloatStruct(
+    float a0,
+    Struct32BytesHomogeneousDouble a1,
+    float a2,
+    Struct32BytesHomogeneousDouble a3,
+    float a4,
+    Struct32BytesHomogeneousDouble a5,
+    float a6,
+    Struct32BytesHomogeneousDouble a7,
+    float a8) {
+  std::cout << "PassFloatStruct32BytesHomogeneousDoubleFloatStruct"
+            << "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
+            << ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
+            << ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
+            << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
+            << ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
+            << "), " << a8 << ")"
+            << "\n";
+
+  double result = 0;
+
+  result += a0;
+  result += a1.a0;
+  result += a1.a1;
+  result += a1.a2;
+  result += a1.a3;
+  result += a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a3.a2;
+  result += a3.a3;
+  result += a4;
+  result += a5.a0;
+  result += a5.a1;
+  result += a5.a2;
+  result += a5.a3;
+  result += a6;
+  result += a7.a0;
+  result += a7.a1;
+  result += a7.a2;
+  result += a7.a3;
+  result += a8;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Tests the alignment of structs in integers registers and on the stack.
+// Arm32 aligns this struct at 8.
+// Also, arm32 allocates the second struct partially in registers, partially
+// on stack.
+// Test backfilling of integer registers.
+DART_EXPORT double PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
+    int8_t a0,
+    Struct16BytesMixed a1,
+    int8_t a2,
+    Struct16BytesMixed a3,
+    int8_t a4,
+    Struct16BytesMixed a5,
+    int8_t a6,
+    Struct16BytesMixed a7,
+    int8_t a8) {
+  std::cout << "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn"
+            << "(" << static_cast<int>(a0) << ", (" << a1.a0 << ", " << a1.a1
+            << "), " << static_cast<int>(a2) << ", (" << a3.a0 << ", " << a3.a1
+            << "), " << static_cast<int>(a4) << ", (" << a5.a0 << ", " << a5.a1
+            << "), " << static_cast<int>(a6) << ", (" << a7.a0 << ", " << a7.a1
+            << "), " << static_cast<int>(a8) << ")"
+            << "\n";
+
+  double result = 0;
+
+  result += a0;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2;
+  result += a3.a0;
+  result += a3.a1;
+  result += a4;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+// structs. The rest of the structs will go on the stack.
+// The int will be backfilled into the int register.
+DART_EXPORT double PassDoublex6Struct16BytesMixedx4Int32(double a0,
+                                                         double a1,
+                                                         double a2,
+                                                         double a3,
+                                                         double a4,
+                                                         double a5,
+                                                         Struct16BytesMixed a6,
+                                                         Struct16BytesMixed a7,
+                                                         Struct16BytesMixed a8,
+                                                         Struct16BytesMixed a9,
+                                                         int32_t a10) {
+  std::cout << "PassDoublex6Struct16BytesMixedx4Int32"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0
+            << ", " << a7.a1 << "), (" << a8.a0 << ", " << a8.a1 << "), ("
+            << a9.a0 << ", " << a9.a1 << "), " << a10 << ")"
+            << "\n";
+
+  double result = 0;
+
+  result += a0;
+  result += a1;
+  result += a2;
+  result += a3;
+  result += a4;
+  result += a5;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8.a0;
+  result += a8.a1;
+  result += a9.a0;
+  result += a9.a1;
+  result += a10;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On Linux x64, it will exhaust int registers first.
+// The rest of the structs will go on the stack.
+// The double will be backfilled into the xmm register.
+DART_EXPORT double PassInt32x4Struct16BytesMixedx4Double(int32_t a0,
+                                                         int32_t a1,
+                                                         int32_t a2,
+                                                         int32_t a3,
+                                                         Struct16BytesMixed a4,
+                                                         Struct16BytesMixed a5,
+                                                         Struct16BytesMixed a6,
+                                                         Struct16BytesMixed a7,
+                                                         double a8) {
+  std::cout << "PassInt32x4Struct16BytesMixedx4Double"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", ("
+            << a4.a0 << ", " << a4.a1 << "), (" << a5.a0 << ", " << a5.a1
+            << "), (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0 << ", "
+            << a7.a1 << "), " << a8 << ")"
+            << "\n";
+
+  double result = 0;
+
+  result += a0;
+  result += a1;
+  result += a2;
+  result += a3;
+  result += a4.a0;
+  result += a4.a1;
+  result += a5.a0;
+  result += a5.a1;
+  result += a6.a0;
+  result += a6.a1;
+  result += a7.a0;
+  result += a7.a1;
+  result += a8;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On various architectures, first struct is allocated on stack.
+// Check that the other two arguments are allocated on registers.
+DART_EXPORT double PassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
+    Struct40BytesHomogeneousDouble a0,
+    Struct4BytesHomogeneousInt16 a1,
+    Struct8BytesHomogeneousFloat a2) {
+  std::cout << "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << "), ("
+            << a2.a0 << ", " << a2.a1 << "))"
+            << "\n";
+
+  double result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+  result += a0.a3;
+  result += a0.a4;
+  result += a1.a0;
+  result += a1.a1;
+  result += a2.a0;
+  result += a2.a1;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 16 byte int within struct.
+DART_EXPORT int64_t PassStructAlignmentInt16(StructAlignmentInt16 a0) {
+  std::cout << "PassStructAlignmentInt16"
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 32 byte int within struct.
+DART_EXPORT int64_t PassStructAlignmentInt32(StructAlignmentInt32 a0) {
+  std::cout << "PassStructAlignmentInt32"
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 64 byte int within struct.
+DART_EXPORT int64_t PassStructAlignmentInt64(StructAlignmentInt64 a0) {
+  std::cout << "PassStructAlignmentInt64"
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << "))"
+            << "\n";
+
+  int64_t result = 0;
+
+  result += a0.a0;
+  result += a0.a1;
+  result += a0.a2;
+
+  std::cout << "result = " << result << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Smallest struct with data.
+DART_EXPORT Struct1ByteInt ReturnStruct1ByteInt(int8_t a0) {
+  std::cout << "ReturnStruct1ByteInt"
+            << "(" << static_cast<int>(a0) << ")"
+            << "\n";
+
+  Struct1ByteInt result;
+
+  result.a0 = a0;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Smaller than word size return value on all architectures.
+DART_EXPORT Struct3BytesInt ReturnStruct3BytesInt(int16_t a0, int8_t a1) {
+  std::cout << "ReturnStruct3BytesInt"
+            << "(" << a0 << ", " << static_cast<int>(a1) << ")"
+            << "\n";
+
+  Struct3BytesInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Word size return value on 32 bit architectures..
+DART_EXPORT Struct4BytesHomogeneousInt16
+ReturnStruct4BytesHomogeneousInt16(int16_t a0, int16_t a1) {
+  std::cout << "ReturnStruct4BytesHomogeneousInt16"
+            << "(" << a0 << ", " << a1 << ")"
+            << "\n";
+
+  Struct4BytesHomogeneousInt16 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Non-wordsize return value.
+DART_EXPORT Struct7BytesInt ReturnStruct7BytesInt(int32_t a0,
+                                                  int16_t a1,
+                                                  int8_t a2) {
+  std::cout << "ReturnStruct7BytesInt"
+            << "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
+            << "\n";
+
+  Struct7BytesInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value in integer registers on many architectures.
+DART_EXPORT Struct8BytesInt ReturnStruct8BytesInt(int16_t a0,
+                                                  int16_t a1,
+                                                  int32_t a2) {
+  std::cout << "ReturnStruct8BytesInt"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ")"
+            << "\n";
+
+  Struct8BytesInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value in FP registers on many architectures.
+DART_EXPORT Struct8BytesHomogeneousFloat
+ReturnStruct8BytesHomogeneousFloat(float a0, float a1) {
+  std::cout << "ReturnStruct8BytesHomogeneousFloat"
+            << "(" << a0 << ", " << a1 << ")"
+            << "\n";
+
+  Struct8BytesHomogeneousFloat result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value split over FP and integer register in x64.
+DART_EXPORT Struct8BytesMixed ReturnStruct8BytesMixed(float a0,
+                                                      int16_t a1,
+                                                      int16_t a2) {
+  std::cout << "ReturnStruct8BytesMixed"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ")"
+            << "\n";
+
+  Struct8BytesMixed result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value in two integer registers on x64.
+// The second register only contains a single byte.
+DART_EXPORT Struct9BytesInt ReturnStruct9BytesInt(int64_t a0, int8_t a1) {
+  std::cout << "ReturnStruct9BytesInt"
+            << "(" << a0 << ", " << static_cast<int>(a1) << ")"
+            << "\n";
+
+  Struct9BytesInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// The minimum alignment of this struct is only 1 byte based on its fields.
+// Test that the memory backing these structs is the right size and that
+// dart:ffi trampolines do not write outside this size.
+DART_EXPORT Struct9BytesHomogeneousUint82
+ReturnStruct9BytesHomogeneousUint82(uint8_t a0,
+                                    uint8_t a1,
+                                    uint8_t a2,
+                                    uint8_t a3,
+                                    uint8_t a4,
+                                    uint8_t a5,
+                                    uint8_t a6,
+                                    uint8_t a7,
+                                    uint8_t a8) {
+  std::cout << "ReturnStruct9BytesHomogeneousUint82"
+            << "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
+            << ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
+            << ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
+            << ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
+            << ", " << static_cast<int>(a8) << ")"
+            << "\n";
+
+  Struct9BytesHomogeneousUint82 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+  result.a5 = a5;
+  result.a6 = a6;
+  result.a7 = a7;
+  result.a8 = a8;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", "
+            << static_cast<int>(result.a1) << ", "
+            << static_cast<int>(result.a2) << ", "
+            << static_cast<int>(result.a3) << ", "
+            << static_cast<int>(result.a4) << ", "
+            << static_cast<int>(result.a5) << ", "
+            << static_cast<int>(result.a6) << ", "
+            << static_cast<int>(result.a7) << ", "
+            << static_cast<int>(result.a8) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value in FPU registers, but does not use all registers on arm hardfp
+// and arm64.
+DART_EXPORT Struct12BytesHomogeneousFloat
+ReturnStruct12BytesHomogeneousFloat(float a0, float a1, float a2) {
+  std::cout << "ReturnStruct12BytesHomogeneousFloat"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ")"
+            << "\n";
+
+  Struct12BytesHomogeneousFloat result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value in FPU registers on arm hardfp and arm64.
+DART_EXPORT Struct16BytesHomogeneousFloat
+ReturnStruct16BytesHomogeneousFloat(float a0, float a1, float a2, float a3) {
+  std::cout << "ReturnStruct16BytesHomogeneousFloat"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
+            << "\n";
+
+  Struct16BytesHomogeneousFloat result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value split over FP and integer register in x64.
+DART_EXPORT Struct16BytesMixed ReturnStruct16BytesMixed(double a0, int64_t a1) {
+  std::cout << "ReturnStruct16BytesMixed"
+            << "(" << a0 << ", " << a1 << ")"
+            << "\n";
+
+  Struct16BytesMixed result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value split over FP and integer register in x64.
+// The integer register contains half float half int.
+DART_EXPORT Struct16BytesMixed2 ReturnStruct16BytesMixed2(float a0,
+                                                          float a1,
+                                                          float a2,
+                                                          int32_t a3) {
+  std::cout << "ReturnStruct16BytesMixed2"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
+            << "\n";
+
+  Struct16BytesMixed2 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Rerturn value returned in preallocated space passed by pointer on most ABIs.
+// Is non word size on purpose, to test that structs are rounded up to word size
+// on all ABIs.
+DART_EXPORT Struct17BytesInt ReturnStruct17BytesInt(int64_t a0,
+                                                    int64_t a1,
+                                                    int8_t a2) {
+  std::cout << "ReturnStruct17BytesInt"
+            << "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
+            << "\n";
+
+  Struct17BytesInt result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// The minimum alignment of this struct is only 1 byte based on its fields.
+// Test that the memory backing these structs is the right size and that
+// dart:ffi trampolines do not write outside this size.
+DART_EXPORT Struct19BytesHomogeneousUint8
+ReturnStruct19BytesHomogeneousUint8(uint8_t a0,
+                                    uint8_t a1,
+                                    uint8_t a2,
+                                    uint8_t a3,
+                                    uint8_t a4,
+                                    uint8_t a5,
+                                    uint8_t a6,
+                                    uint8_t a7,
+                                    uint8_t a8,
+                                    uint8_t a9,
+                                    uint8_t a10,
+                                    uint8_t a11,
+                                    uint8_t a12,
+                                    uint8_t a13,
+                                    uint8_t a14,
+                                    uint8_t a15,
+                                    uint8_t a16,
+                                    uint8_t a17,
+                                    uint8_t a18) {
+  std::cout << "ReturnStruct19BytesHomogeneousUint8"
+            << "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
+            << ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
+            << ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
+            << ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
+            << ", " << static_cast<int>(a8) << ", " << static_cast<int>(a9)
+            << ", " << static_cast<int>(a10) << ", " << static_cast<int>(a11)
+            << ", " << static_cast<int>(a12) << ", " << static_cast<int>(a13)
+            << ", " << static_cast<int>(a14) << ", " << static_cast<int>(a15)
+            << ", " << static_cast<int>(a16) << ", " << static_cast<int>(a17)
+            << ", " << static_cast<int>(a18) << ")"
+            << "\n";
+
+  Struct19BytesHomogeneousUint8 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+  result.a5 = a5;
+  result.a6 = a6;
+  result.a7 = a7;
+  result.a8 = a8;
+  result.a9 = a9;
+  result.a10 = a10;
+  result.a11 = a11;
+  result.a12 = a12;
+  result.a13 = a13;
+  result.a14 = a14;
+  result.a15 = a15;
+  result.a16 = a16;
+  result.a17 = a17;
+  result.a18 = a18;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", "
+            << static_cast<int>(result.a1) << ", "
+            << static_cast<int>(result.a2) << ", "
+            << static_cast<int>(result.a3) << ", "
+            << static_cast<int>(result.a4) << ", "
+            << static_cast<int>(result.a5) << ", "
+            << static_cast<int>(result.a6) << ", "
+            << static_cast<int>(result.a7) << ", "
+            << static_cast<int>(result.a8) << ", "
+            << static_cast<int>(result.a9) << ", "
+            << static_cast<int>(result.a10) << ", "
+            << static_cast<int>(result.a11) << ", "
+            << static_cast<int>(result.a12) << ", "
+            << static_cast<int>(result.a13) << ", "
+            << static_cast<int>(result.a14) << ", "
+            << static_cast<int>(result.a15) << ", "
+            << static_cast<int>(result.a16) << ", "
+            << static_cast<int>(result.a17) << ", "
+            << static_cast<int>(result.a18) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value too big to go in cpu registers on arm64.
+DART_EXPORT Struct20BytesHomogeneousInt32
+ReturnStruct20BytesHomogeneousInt32(int32_t a0,
+                                    int32_t a1,
+                                    int32_t a2,
+                                    int32_t a3,
+                                    int32_t a4) {
+  std::cout << "ReturnStruct20BytesHomogeneousInt32"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ")"
+            << "\n";
+
+  Struct20BytesHomogeneousInt32 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
+DART_EXPORT Struct20BytesHomogeneousFloat
+ReturnStruct20BytesHomogeneousFloat(float a0,
+                                    float a1,
+                                    float a2,
+                                    float a3,
+                                    float a4) {
+  std::cout << "ReturnStruct20BytesHomogeneousFloat"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ")"
+            << "\n";
+
+  Struct20BytesHomogeneousFloat result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value in FPU registers on arm64.
+DART_EXPORT Struct32BytesHomogeneousDouble
+ReturnStruct32BytesHomogeneousDouble(double a0,
+                                     double a1,
+                                     double a2,
+                                     double a3) {
+  std::cout << "ReturnStruct32BytesHomogeneousDouble"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
+            << "\n";
+
+  Struct32BytesHomogeneousDouble result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Return value too big to go in FPU registers on arm64.
+DART_EXPORT Struct40BytesHomogeneousDouble
+ReturnStruct40BytesHomogeneousDouble(double a0,
+                                     double a1,
+                                     double a2,
+                                     double a3,
+                                     double a4) {
+  std::cout << "ReturnStruct40BytesHomogeneousDouble"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ")"
+            << "\n";
+
+  Struct40BytesHomogeneousDouble result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test 1kb struct.
+DART_EXPORT Struct1024BytesHomogeneousUint64
+ReturnStruct1024BytesHomogeneousUint64(uint64_t a0,
+                                       uint64_t a1,
+                                       uint64_t a2,
+                                       uint64_t a3,
+                                       uint64_t a4,
+                                       uint64_t a5,
+                                       uint64_t a6,
+                                       uint64_t a7,
+                                       uint64_t a8,
+                                       uint64_t a9,
+                                       uint64_t a10,
+                                       uint64_t a11,
+                                       uint64_t a12,
+                                       uint64_t a13,
+                                       uint64_t a14,
+                                       uint64_t a15,
+                                       uint64_t a16,
+                                       uint64_t a17,
+                                       uint64_t a18,
+                                       uint64_t a19,
+                                       uint64_t a20,
+                                       uint64_t a21,
+                                       uint64_t a22,
+                                       uint64_t a23,
+                                       uint64_t a24,
+                                       uint64_t a25,
+                                       uint64_t a26,
+                                       uint64_t a27,
+                                       uint64_t a28,
+                                       uint64_t a29,
+                                       uint64_t a30,
+                                       uint64_t a31,
+                                       uint64_t a32,
+                                       uint64_t a33,
+                                       uint64_t a34,
+                                       uint64_t a35,
+                                       uint64_t a36,
+                                       uint64_t a37,
+                                       uint64_t a38,
+                                       uint64_t a39,
+                                       uint64_t a40,
+                                       uint64_t a41,
+                                       uint64_t a42,
+                                       uint64_t a43,
+                                       uint64_t a44,
+                                       uint64_t a45,
+                                       uint64_t a46,
+                                       uint64_t a47,
+                                       uint64_t a48,
+                                       uint64_t a49,
+                                       uint64_t a50,
+                                       uint64_t a51,
+                                       uint64_t a52,
+                                       uint64_t a53,
+                                       uint64_t a54,
+                                       uint64_t a55,
+                                       uint64_t a56,
+                                       uint64_t a57,
+                                       uint64_t a58,
+                                       uint64_t a59,
+                                       uint64_t a60,
+                                       uint64_t a61,
+                                       uint64_t a62,
+                                       uint64_t a63,
+                                       uint64_t a64,
+                                       uint64_t a65,
+                                       uint64_t a66,
+                                       uint64_t a67,
+                                       uint64_t a68,
+                                       uint64_t a69,
+                                       uint64_t a70,
+                                       uint64_t a71,
+                                       uint64_t a72,
+                                       uint64_t a73,
+                                       uint64_t a74,
+                                       uint64_t a75,
+                                       uint64_t a76,
+                                       uint64_t a77,
+                                       uint64_t a78,
+                                       uint64_t a79,
+                                       uint64_t a80,
+                                       uint64_t a81,
+                                       uint64_t a82,
+                                       uint64_t a83,
+                                       uint64_t a84,
+                                       uint64_t a85,
+                                       uint64_t a86,
+                                       uint64_t a87,
+                                       uint64_t a88,
+                                       uint64_t a89,
+                                       uint64_t a90,
+                                       uint64_t a91,
+                                       uint64_t a92,
+                                       uint64_t a93,
+                                       uint64_t a94,
+                                       uint64_t a95,
+                                       uint64_t a96,
+                                       uint64_t a97,
+                                       uint64_t a98,
+                                       uint64_t a99,
+                                       uint64_t a100,
+                                       uint64_t a101,
+                                       uint64_t a102,
+                                       uint64_t a103,
+                                       uint64_t a104,
+                                       uint64_t a105,
+                                       uint64_t a106,
+                                       uint64_t a107,
+                                       uint64_t a108,
+                                       uint64_t a109,
+                                       uint64_t a110,
+                                       uint64_t a111,
+                                       uint64_t a112,
+                                       uint64_t a113,
+                                       uint64_t a114,
+                                       uint64_t a115,
+                                       uint64_t a116,
+                                       uint64_t a117,
+                                       uint64_t a118,
+                                       uint64_t a119,
+                                       uint64_t a120,
+                                       uint64_t a121,
+                                       uint64_t a122,
+                                       uint64_t a123,
+                                       uint64_t a124,
+                                       uint64_t a125,
+                                       uint64_t a126,
+                                       uint64_t a127) {
+  std::cout << "ReturnStruct1024BytesHomogeneousUint64"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
+            << a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
+            << ", " << a14 << ", " << a15 << ", " << a16 << ", " << a17 << ", "
+            << a18 << ", " << a19 << ", " << a20 << ", " << a21 << ", " << a22
+            << ", " << a23 << ", " << a24 << ", " << a25 << ", " << a26 << ", "
+            << a27 << ", " << a28 << ", " << a29 << ", " << a30 << ", " << a31
+            << ", " << a32 << ", " << a33 << ", " << a34 << ", " << a35 << ", "
+            << a36 << ", " << a37 << ", " << a38 << ", " << a39 << ", " << a40
+            << ", " << a41 << ", " << a42 << ", " << a43 << ", " << a44 << ", "
+            << a45 << ", " << a46 << ", " << a47 << ", " << a48 << ", " << a49
+            << ", " << a50 << ", " << a51 << ", " << a52 << ", " << a53 << ", "
+            << a54 << ", " << a55 << ", " << a56 << ", " << a57 << ", " << a58
+            << ", " << a59 << ", " << a60 << ", " << a61 << ", " << a62 << ", "
+            << a63 << ", " << a64 << ", " << a65 << ", " << a66 << ", " << a67
+            << ", " << a68 << ", " << a69 << ", " << a70 << ", " << a71 << ", "
+            << a72 << ", " << a73 << ", " << a74 << ", " << a75 << ", " << a76
+            << ", " << a77 << ", " << a78 << ", " << a79 << ", " << a80 << ", "
+            << a81 << ", " << a82 << ", " << a83 << ", " << a84 << ", " << a85
+            << ", " << a86 << ", " << a87 << ", " << a88 << ", " << a89 << ", "
+            << a90 << ", " << a91 << ", " << a92 << ", " << a93 << ", " << a94
+            << ", " << a95 << ", " << a96 << ", " << a97 << ", " << a98 << ", "
+            << a99 << ", " << a100 << ", " << a101 << ", " << a102 << ", "
+            << a103 << ", " << a104 << ", " << a105 << ", " << a106 << ", "
+            << a107 << ", " << a108 << ", " << a109 << ", " << a110 << ", "
+            << a111 << ", " << a112 << ", " << a113 << ", " << a114 << ", "
+            << a115 << ", " << a116 << ", " << a117 << ", " << a118 << ", "
+            << a119 << ", " << a120 << ", " << a121 << ", " << a122 << ", "
+            << a123 << ", " << a124 << ", " << a125 << ", " << a126 << ", "
+            << a127 << ")"
+            << "\n";
+
+  Struct1024BytesHomogeneousUint64 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+  result.a3 = a3;
+  result.a4 = a4;
+  result.a5 = a5;
+  result.a6 = a6;
+  result.a7 = a7;
+  result.a8 = a8;
+  result.a9 = a9;
+  result.a10 = a10;
+  result.a11 = a11;
+  result.a12 = a12;
+  result.a13 = a13;
+  result.a14 = a14;
+  result.a15 = a15;
+  result.a16 = a16;
+  result.a17 = a17;
+  result.a18 = a18;
+  result.a19 = a19;
+  result.a20 = a20;
+  result.a21 = a21;
+  result.a22 = a22;
+  result.a23 = a23;
+  result.a24 = a24;
+  result.a25 = a25;
+  result.a26 = a26;
+  result.a27 = a27;
+  result.a28 = a28;
+  result.a29 = a29;
+  result.a30 = a30;
+  result.a31 = a31;
+  result.a32 = a32;
+  result.a33 = a33;
+  result.a34 = a34;
+  result.a35 = a35;
+  result.a36 = a36;
+  result.a37 = a37;
+  result.a38 = a38;
+  result.a39 = a39;
+  result.a40 = a40;
+  result.a41 = a41;
+  result.a42 = a42;
+  result.a43 = a43;
+  result.a44 = a44;
+  result.a45 = a45;
+  result.a46 = a46;
+  result.a47 = a47;
+  result.a48 = a48;
+  result.a49 = a49;
+  result.a50 = a50;
+  result.a51 = a51;
+  result.a52 = a52;
+  result.a53 = a53;
+  result.a54 = a54;
+  result.a55 = a55;
+  result.a56 = a56;
+  result.a57 = a57;
+  result.a58 = a58;
+  result.a59 = a59;
+  result.a60 = a60;
+  result.a61 = a61;
+  result.a62 = a62;
+  result.a63 = a63;
+  result.a64 = a64;
+  result.a65 = a65;
+  result.a66 = a66;
+  result.a67 = a67;
+  result.a68 = a68;
+  result.a69 = a69;
+  result.a70 = a70;
+  result.a71 = a71;
+  result.a72 = a72;
+  result.a73 = a73;
+  result.a74 = a74;
+  result.a75 = a75;
+  result.a76 = a76;
+  result.a77 = a77;
+  result.a78 = a78;
+  result.a79 = a79;
+  result.a80 = a80;
+  result.a81 = a81;
+  result.a82 = a82;
+  result.a83 = a83;
+  result.a84 = a84;
+  result.a85 = a85;
+  result.a86 = a86;
+  result.a87 = a87;
+  result.a88 = a88;
+  result.a89 = a89;
+  result.a90 = a90;
+  result.a91 = a91;
+  result.a92 = a92;
+  result.a93 = a93;
+  result.a94 = a94;
+  result.a95 = a95;
+  result.a96 = a96;
+  result.a97 = a97;
+  result.a98 = a98;
+  result.a99 = a99;
+  result.a100 = a100;
+  result.a101 = a101;
+  result.a102 = a102;
+  result.a103 = a103;
+  result.a104 = a104;
+  result.a105 = a105;
+  result.a106 = a106;
+  result.a107 = a107;
+  result.a108 = a108;
+  result.a109 = a109;
+  result.a110 = a110;
+  result.a111 = a111;
+  result.a112 = a112;
+  result.a113 = a113;
+  result.a114 = a114;
+  result.a115 = a115;
+  result.a116 = a116;
+  result.a117 = a117;
+  result.a118 = a118;
+  result.a119 = a119;
+  result.a120 = a120;
+  result.a121 = a121;
+  result.a122 = a122;
+  result.a123 = a123;
+  result.a124 = a124;
+  result.a125 = a125;
+  result.a126 = a126;
+  result.a127 = a127;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ", " << result.a5
+            << ", " << result.a6 << ", " << result.a7 << ", " << result.a8
+            << ", " << result.a9 << ", " << result.a10 << ", " << result.a11
+            << ", " << result.a12 << ", " << result.a13 << ", " << result.a14
+            << ", " << result.a15 << ", " << result.a16 << ", " << result.a17
+            << ", " << result.a18 << ", " << result.a19 << ", " << result.a20
+            << ", " << result.a21 << ", " << result.a22 << ", " << result.a23
+            << ", " << result.a24 << ", " << result.a25 << ", " << result.a26
+            << ", " << result.a27 << ", " << result.a28 << ", " << result.a29
+            << ", " << result.a30 << ", " << result.a31 << ", " << result.a32
+            << ", " << result.a33 << ", " << result.a34 << ", " << result.a35
+            << ", " << result.a36 << ", " << result.a37 << ", " << result.a38
+            << ", " << result.a39 << ", " << result.a40 << ", " << result.a41
+            << ", " << result.a42 << ", " << result.a43 << ", " << result.a44
+            << ", " << result.a45 << ", " << result.a46 << ", " << result.a47
+            << ", " << result.a48 << ", " << result.a49 << ", " << result.a50
+            << ", " << result.a51 << ", " << result.a52 << ", " << result.a53
+            << ", " << result.a54 << ", " << result.a55 << ", " << result.a56
+            << ", " << result.a57 << ", " << result.a58 << ", " << result.a59
+            << ", " << result.a60 << ", " << result.a61 << ", " << result.a62
+            << ", " << result.a63 << ", " << result.a64 << ", " << result.a65
+            << ", " << result.a66 << ", " << result.a67 << ", " << result.a68
+            << ", " << result.a69 << ", " << result.a70 << ", " << result.a71
+            << ", " << result.a72 << ", " << result.a73 << ", " << result.a74
+            << ", " << result.a75 << ", " << result.a76 << ", " << result.a77
+            << ", " << result.a78 << ", " << result.a79 << ", " << result.a80
+            << ", " << result.a81 << ", " << result.a82 << ", " << result.a83
+            << ", " << result.a84 << ", " << result.a85 << ", " << result.a86
+            << ", " << result.a87 << ", " << result.a88 << ", " << result.a89
+            << ", " << result.a90 << ", " << result.a91 << ", " << result.a92
+            << ", " << result.a93 << ", " << result.a94 << ", " << result.a95
+            << ", " << result.a96 << ", " << result.a97 << ", " << result.a98
+            << ", " << result.a99 << ", " << result.a100 << ", " << result.a101
+            << ", " << result.a102 << ", " << result.a103 << ", " << result.a104
+            << ", " << result.a105 << ", " << result.a106 << ", " << result.a107
+            << ", " << result.a108 << ", " << result.a109 << ", " << result.a110
+            << ", " << result.a111 << ", " << result.a112 << ", " << result.a113
+            << ", " << result.a114 << ", " << result.a115 << ", " << result.a116
+            << ", " << result.a117 << ", " << result.a118 << ", " << result.a119
+            << ", " << result.a120 << ", " << result.a121 << ", " << result.a122
+            << ", " << result.a123 << ", " << result.a124 << ", " << result.a125
+            << ", " << result.a126 << ", " << result.a127 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test that a struct passed in as argument can be returned.
+// Especially for ffi callbacks.
+// Struct is passed in int registers in most ABIs.
+DART_EXPORT Struct1ByteInt
+ReturnStructArgumentStruct1ByteInt(Struct1ByteInt a0) {
+  std::cout << "ReturnStructArgumentStruct1ByteInt"
+            << "((" << static_cast<int>(a0.a0) << "))"
+            << "\n";
+
+  Struct1ByteInt result = a0;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test that a struct passed in as argument can be returned.
+// Especially for ffi callbacks.
+// Struct is passed on stack on all ABIs.
+DART_EXPORT Struct1ByteInt
+ReturnStructArgumentInt32x8Struct1ByteInt(int32_t a0,
+                                          int32_t a1,
+                                          int32_t a2,
+                                          int32_t a3,
+                                          int32_t a4,
+                                          int32_t a5,
+                                          int32_t a6,
+                                          int32_t a7,
+                                          Struct1ByteInt a8) {
+  std::cout << "ReturnStructArgumentInt32x8Struct1ByteInt"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", " << a6 << ", " << a7 << ", ("
+            << static_cast<int>(a8.a0) << "))"
+            << "\n";
+
+  Struct1ByteInt result = a8;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test that a struct passed in as argument can be returned.
+// Especially for ffi callbacks.
+// Struct is passed in float registers in most ABIs.
+DART_EXPORT Struct8BytesHomogeneousFloat
+ReturnStructArgumentStruct8BytesHomogeneousFloat(
+    Struct8BytesHomogeneousFloat a0) {
+  std::cout << "ReturnStructArgumentStruct8BytesHomogeneousFloat"
+            << "((" << a0.a0 << ", " << a0.a1 << "))"
+            << "\n";
+
+  Struct8BytesHomogeneousFloat result = a0;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On arm64, both argument and return value are passed in by pointer.
+DART_EXPORT Struct20BytesHomogeneousInt32
+ReturnStructArgumentStruct20BytesHomogeneousInt32(
+    Struct20BytesHomogeneousInt32 a0) {
+  std::cout << "ReturnStructArgumentStruct20BytesHomogeneousInt32"
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "))"
+            << "\n";
+
+  Struct20BytesHomogeneousInt32 result = a0;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// On arm64, both argument and return value are passed in by pointer.
+// Ints exhaust registers, so that pointer is passed on stack.
+DART_EXPORT Struct20BytesHomogeneousInt32
+ReturnStructArgumentInt32x8Struct20BytesHomogeneou(
+    int32_t a0,
+    int32_t a1,
+    int32_t a2,
+    int32_t a3,
+    int32_t a4,
+    int32_t a5,
+    int32_t a6,
+    int32_t a7,
+    Struct20BytesHomogeneousInt32 a8) {
+  std::cout << "ReturnStructArgumentInt32x8Struct20BytesHomogeneou"
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", " << a6 << ", " << a7 << ", (" << a8.a0 << ", "
+            << a8.a1 << ", " << a8.a2 << ", " << a8.a3 << ", " << a8.a4 << "))"
+            << "\n";
+
+  Struct20BytesHomogeneousInt32 result = a8;
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 16 byte int within struct.
+DART_EXPORT StructAlignmentInt16 ReturnStructAlignmentInt16(int8_t a0,
+                                                            int16_t a1,
+                                                            int8_t a2) {
+  std::cout << "ReturnStructAlignmentInt16"
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ")"
+            << "\n";
+
+  StructAlignmentInt16 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 32 byte int within struct.
+DART_EXPORT StructAlignmentInt32 ReturnStructAlignmentInt32(int8_t a0,
+                                                            int32_t a1,
+                                                            int8_t a2) {
+  std::cout << "ReturnStructAlignmentInt32"
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ")"
+            << "\n";
+
+  StructAlignmentInt32 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 64 byte int within struct.
+DART_EXPORT StructAlignmentInt64 ReturnStructAlignmentInt64(int8_t a0,
+                                                            int64_t a1,
+                                                            int8_t a2) {
+  std::cout << "ReturnStructAlignmentInt64"
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ")"
+            << "\n";
+
+  StructAlignmentInt64 result;
+
+  result.a0 = a0;
+  result.a1 = a1;
+  result.a2 = a2;
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  return result;
+}
+
+// Used for testing structs by value.
+// Smallest struct with data.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct1ByteIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct1ByteInt a0,
+                 Struct1ByteInt a1,
+                 Struct1ByteInt a2,
+                 Struct1ByteInt a3,
+                 Struct1ByteInt a4,
+                 Struct1ByteInt a5,
+                 Struct1ByteInt a6,
+                 Struct1ByteInt a7,
+                 Struct1ByteInt a8,
+                 Struct1ByteInt a9)) {
+  Struct1ByteInt a0;
+  Struct1ByteInt a1;
+  Struct1ByteInt a2;
+  Struct1ByteInt a3;
+  Struct1ByteInt a4;
+  Struct1ByteInt a5;
+  Struct1ByteInt a6;
+  Struct1ByteInt a7;
+  Struct1ByteInt a8;
+  Struct1ByteInt a9;
+
+  a0.a0 = -1;
+  a1.a0 = 2;
+  a2.a0 = -3;
+  a3.a0 = 4;
+  a4.a0 = -5;
+  a5.a0 = 6;
+  a6.a0 = -7;
+  a7.a0 = 8;
+  a8.a0 = -9;
+  a9.a0 = 10;
+
+  std::cout << "Calling TestPassStruct1ByteIntx10("
+            << "((" << static_cast<int>(a0.a0) << "), ("
+            << static_cast<int>(a1.a0) << "), (" << static_cast<int>(a2.a0)
+            << "), (" << static_cast<int>(a3.a0) << "), ("
+            << static_cast<int>(a4.a0) << "), (" << static_cast<int>(a5.a0)
+            << "), (" << static_cast<int>(a6.a0) << "), ("
+            << static_cast<int>(a7.a0) << "), (" << static_cast<int>(a8.a0)
+            << "), (" << static_cast<int>(a9.a0) << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(5, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Not a multiple of word size, not a power of two.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct3BytesIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct3BytesInt a0,
+                 Struct3BytesInt a1,
+                 Struct3BytesInt a2,
+                 Struct3BytesInt a3,
+                 Struct3BytesInt a4,
+                 Struct3BytesInt a5,
+                 Struct3BytesInt a6,
+                 Struct3BytesInt a7,
+                 Struct3BytesInt a8,
+                 Struct3BytesInt a9)) {
+  Struct3BytesInt a0;
+  Struct3BytesInt a1;
+  Struct3BytesInt a2;
+  Struct3BytesInt a3;
+  Struct3BytesInt a4;
+  Struct3BytesInt a5;
+  Struct3BytesInt a6;
+  Struct3BytesInt a7;
+  Struct3BytesInt a8;
+  Struct3BytesInt a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  std::cout << "Calling TestPassStruct3BytesIntx10("
+            << "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
+            << a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
+            << ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
+            << static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
+            << static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
+            << static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
+            << static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
+            << static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
+            << static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
+            << static_cast<int>(a9.a1) << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(10, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Exactly word size on 32-bit architectures.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct4BytesHomogeneousInt16x10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct4BytesHomogeneousInt16 a0,
+                 Struct4BytesHomogeneousInt16 a1,
+                 Struct4BytesHomogeneousInt16 a2,
+                 Struct4BytesHomogeneousInt16 a3,
+                 Struct4BytesHomogeneousInt16 a4,
+                 Struct4BytesHomogeneousInt16 a5,
+                 Struct4BytesHomogeneousInt16 a6,
+                 Struct4BytesHomogeneousInt16 a7,
+                 Struct4BytesHomogeneousInt16 a8,
+                 Struct4BytesHomogeneousInt16 a9)) {
+  Struct4BytesHomogeneousInt16 a0;
+  Struct4BytesHomogeneousInt16 a1;
+  Struct4BytesHomogeneousInt16 a2;
+  Struct4BytesHomogeneousInt16 a3;
+  Struct4BytesHomogeneousInt16 a4;
+  Struct4BytesHomogeneousInt16 a5;
+  Struct4BytesHomogeneousInt16 a6;
+  Struct4BytesHomogeneousInt16 a7;
+  Struct4BytesHomogeneousInt16 a8;
+  Struct4BytesHomogeneousInt16 a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  std::cout << "Calling TestPassStruct4BytesHomogeneousInt16x10("
+            << "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
+            << a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
+            << ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
+            << a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
+            << "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
+            << a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(10, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Sub word size on 64 bit architectures.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct7BytesIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct7BytesInt a0,
+                 Struct7BytesInt a1,
+                 Struct7BytesInt a2,
+                 Struct7BytesInt a3,
+                 Struct7BytesInt a4,
+                 Struct7BytesInt a5,
+                 Struct7BytesInt a6,
+                 Struct7BytesInt a7,
+                 Struct7BytesInt a8,
+                 Struct7BytesInt a9)) {
+  Struct7BytesInt a0;
+  Struct7BytesInt a1;
+  Struct7BytesInt a2;
+  Struct7BytesInt a3;
+  Struct7BytesInt a4;
+  Struct7BytesInt a5;
+  Struct7BytesInt a6;
+  Struct7BytesInt a7;
+  Struct7BytesInt a8;
+  Struct7BytesInt a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  std::cout << "Calling TestPassStruct7BytesIntx10("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
+            << "), (" << a1.a0 << ", " << a1.a1 << ", "
+            << static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
+            << ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
+            << ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
+            << a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
+            << "), (" << a6.a0 << ", " << a6.a1 << ", "
+            << static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
+            << ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
+            << a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(15, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Exactly word size struct on 64bit architectures.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct8BytesIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct8BytesInt a0,
+                 Struct8BytesInt a1,
+                 Struct8BytesInt a2,
+                 Struct8BytesInt a3,
+                 Struct8BytesInt a4,
+                 Struct8BytesInt a5,
+                 Struct8BytesInt a6,
+                 Struct8BytesInt a7,
+                 Struct8BytesInt a8,
+                 Struct8BytesInt a9)) {
+  Struct8BytesInt a0;
+  Struct8BytesInt a1;
+  Struct8BytesInt a2;
+  Struct8BytesInt a3;
+  Struct8BytesInt a4;
+  Struct8BytesInt a5;
+  Struct8BytesInt a6;
+  Struct8BytesInt a7;
+  Struct8BytesInt a8;
+  Struct8BytesInt a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  std::cout << "Calling TestPassStruct8BytesIntx10("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
+            << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
+            << a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
+            << "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
+            << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << a9.a2 << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(15, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Arguments passed in FP registers as long as they fit.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct8BytesHomogeneousFloatx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(Struct8BytesHomogeneousFloat a0,
+               Struct8BytesHomogeneousFloat a1,
+               Struct8BytesHomogeneousFloat a2,
+               Struct8BytesHomogeneousFloat a3,
+               Struct8BytesHomogeneousFloat a4,
+               Struct8BytesHomogeneousFloat a5,
+               Struct8BytesHomogeneousFloat a6,
+               Struct8BytesHomogeneousFloat a7,
+               Struct8BytesHomogeneousFloat a8,
+               Struct8BytesHomogeneousFloat a9)) {
+  Struct8BytesHomogeneousFloat a0;
+  Struct8BytesHomogeneousFloat a1;
+  Struct8BytesHomogeneousFloat a2;
+  Struct8BytesHomogeneousFloat a3;
+  Struct8BytesHomogeneousFloat a4;
+  Struct8BytesHomogeneousFloat a5;
+  Struct8BytesHomogeneousFloat a6;
+  Struct8BytesHomogeneousFloat a7;
+  Struct8BytesHomogeneousFloat a8;
+  Struct8BytesHomogeneousFloat a9;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a1.a0 = -3.0;
+  a1.a1 = 4.0;
+  a2.a0 = -5.0;
+  a2.a1 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a4.a0 = -9.0;
+  a4.a1 = 10.0;
+  a5.a0 = -11.0;
+  a5.a1 = 12.0;
+  a6.a0 = -13.0;
+  a6.a1 = 14.0;
+  a7.a0 = -15.0;
+  a7.a1 = 16.0;
+  a8.a0 = -17.0;
+  a8.a1 = 18.0;
+  a9.a0 = -19.0;
+  a9.a1 = 20.0;
+
+  std::cout << "Calling TestPassStruct8BytesHomogeneousFloatx10("
+            << "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
+            << a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
+            << ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
+            << a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
+            << "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
+            << a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
+            << ")\n";
+
+  float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(10.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On x64, arguments go in int registers because it is not only float.
+// 10 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct8BytesMixedx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(Struct8BytesMixed a0,
+               Struct8BytesMixed a1,
+               Struct8BytesMixed a2,
+               Struct8BytesMixed a3,
+               Struct8BytesMixed a4,
+               Struct8BytesMixed a5,
+               Struct8BytesMixed a6,
+               Struct8BytesMixed a7,
+               Struct8BytesMixed a8,
+               Struct8BytesMixed a9)) {
+  Struct8BytesMixed a0;
+  Struct8BytesMixed a1;
+  Struct8BytesMixed a2;
+  Struct8BytesMixed a3;
+  Struct8BytesMixed a4;
+  Struct8BytesMixed a5;
+  Struct8BytesMixed a6;
+  Struct8BytesMixed a7;
+  Struct8BytesMixed a8;
+  Struct8BytesMixed a9;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4.0;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7.0;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10.0;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13.0;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16.0;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19.0;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22.0;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25.0;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28.0;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  std::cout << "Calling TestPassStruct8BytesMixedx10("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
+            << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
+            << a5.a2 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
+            << "), (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << "), ("
+            << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << a9.a2 << "))"
+            << ")\n";
+
+  float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(15.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Argument is a single byte over a multiple of word size.
+// 10 struct arguments will exhaust available registers.
+// Tests upper bytes in the integer registers that are partly filled.
+// Tests stack alignment of non word size stack arguments.
+DART_EXPORT intptr_t TestPassStruct9BytesIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct9BytesInt a0,
+                 Struct9BytesInt a1,
+                 Struct9BytesInt a2,
+                 Struct9BytesInt a3,
+                 Struct9BytesInt a4,
+                 Struct9BytesInt a5,
+                 Struct9BytesInt a6,
+                 Struct9BytesInt a7,
+                 Struct9BytesInt a8,
+                 Struct9BytesInt a9)) {
+  Struct9BytesInt a0;
+  Struct9BytesInt a1;
+  Struct9BytesInt a2;
+  Struct9BytesInt a3;
+  Struct9BytesInt a4;
+  Struct9BytesInt a5;
+  Struct9BytesInt a6;
+  Struct9BytesInt a7;
+  Struct9BytesInt a8;
+  Struct9BytesInt a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  std::cout << "Calling TestPassStruct9BytesIntx10("
+            << "((" << a0.a0 << ", " << static_cast<int>(a0.a1) << "), ("
+            << a1.a0 << ", " << static_cast<int>(a1.a1) << "), (" << a2.a0
+            << ", " << static_cast<int>(a2.a1) << "), (" << a3.a0 << ", "
+            << static_cast<int>(a3.a1) << "), (" << a4.a0 << ", "
+            << static_cast<int>(a4.a1) << "), (" << a5.a0 << ", "
+            << static_cast<int>(a5.a1) << "), (" << a6.a0 << ", "
+            << static_cast<int>(a6.a1) << "), (" << a7.a0 << ", "
+            << static_cast<int>(a7.a1) << "), (" << a8.a0 << ", "
+            << static_cast<int>(a8.a1) << "), (" << a9.a0 << ", "
+            << static_cast<int>(a9.a1) << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(10, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Argument is a single byte over a multiple of word size.
+// 10 struct arguments will exhaust available registers.
+// Struct only has 1-byte aligned fields to test struct alignment itself.
+//
+DART_EXPORT intptr_t TestPassStruct9BytesHomogeneousUint82x10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct9BytesHomogeneousUint82 a0,
+                 Struct9BytesHomogeneousUint82 a1,
+                 Struct9BytesHomogeneousUint82 a2,
+                 Struct9BytesHomogeneousUint82 a3,
+                 Struct9BytesHomogeneousUint82 a4,
+                 Struct9BytesHomogeneousUint82 a5,
+                 Struct9BytesHomogeneousUint82 a6,
+                 Struct9BytesHomogeneousUint82 a7,
+                 Struct9BytesHomogeneousUint82 a8,
+                 Struct9BytesHomogeneousUint82 a9)) {
+  Struct9BytesHomogeneousUint82 a0;
+  Struct9BytesHomogeneousUint82 a1;
+  Struct9BytesHomogeneousUint82 a2;
+  Struct9BytesHomogeneousUint82 a3;
+  Struct9BytesHomogeneousUint82 a4;
+  Struct9BytesHomogeneousUint82 a5;
+  Struct9BytesHomogeneousUint82 a6;
+  Struct9BytesHomogeneousUint82 a7;
+  Struct9BytesHomogeneousUint82 a8;
+  Struct9BytesHomogeneousUint82 a9;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a1.a0 = 10;
+  a1.a1 = 11;
+  a1.a2 = 12;
+  a1.a3 = 13;
+  a1.a4 = 14;
+  a1.a5 = 15;
+  a1.a6 = 16;
+  a1.a7 = 17;
+  a1.a8 = 18;
+  a2.a0 = 19;
+  a2.a1 = 20;
+  a2.a2 = 21;
+  a2.a3 = 22;
+  a2.a4 = 23;
+  a2.a5 = 24;
+  a2.a6 = 25;
+  a2.a7 = 26;
+  a2.a8 = 27;
+  a3.a0 = 28;
+  a3.a1 = 29;
+  a3.a2 = 30;
+  a3.a3 = 31;
+  a3.a4 = 32;
+  a3.a5 = 33;
+  a3.a6 = 34;
+  a3.a7 = 35;
+  a3.a8 = 36;
+  a4.a0 = 37;
+  a4.a1 = 38;
+  a4.a2 = 39;
+  a4.a3 = 40;
+  a4.a4 = 41;
+  a4.a5 = 42;
+  a4.a6 = 43;
+  a4.a7 = 44;
+  a4.a8 = 45;
+  a5.a0 = 46;
+  a5.a1 = 47;
+  a5.a2 = 48;
+  a5.a3 = 49;
+  a5.a4 = 50;
+  a5.a5 = 51;
+  a5.a6 = 52;
+  a5.a7 = 53;
+  a5.a8 = 54;
+  a6.a0 = 55;
+  a6.a1 = 56;
+  a6.a2 = 57;
+  a6.a3 = 58;
+  a6.a4 = 59;
+  a6.a5 = 60;
+  a6.a6 = 61;
+  a6.a7 = 62;
+  a6.a8 = 63;
+  a7.a0 = 64;
+  a7.a1 = 65;
+  a7.a2 = 66;
+  a7.a3 = 67;
+  a7.a4 = 68;
+  a7.a5 = 69;
+  a7.a6 = 70;
+  a7.a7 = 71;
+  a7.a8 = 72;
+  a8.a0 = 73;
+  a8.a1 = 74;
+  a8.a2 = 75;
+  a8.a3 = 76;
+  a8.a4 = 77;
+  a8.a5 = 78;
+  a8.a6 = 79;
+  a8.a7 = 80;
+  a8.a8 = 81;
+  a9.a0 = 82;
+  a9.a1 = 83;
+  a9.a2 = 84;
+  a9.a3 = 85;
+  a9.a4 = 86;
+  a9.a5 = 87;
+  a9.a6 = 88;
+  a9.a7 = 89;
+  a9.a8 = 90;
+
+  std::cout
+      << "Calling TestPassStruct9BytesHomogeneousUint82x10("
+      << "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
+      << ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
+      << ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
+      << ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
+      << ", " << static_cast<int>(a0.a8) << "), (" << static_cast<int>(a1.a0)
+      << ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
+      << ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
+      << ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
+      << ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
+      << "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
+      << ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
+      << ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
+      << ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
+      << ", " << static_cast<int>(a2.a8) << "), (" << static_cast<int>(a3.a0)
+      << ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
+      << ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
+      << ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
+      << ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
+      << "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
+      << ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
+      << ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
+      << ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
+      << ", " << static_cast<int>(a4.a8) << "), (" << static_cast<int>(a5.a0)
+      << ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
+      << ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
+      << ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
+      << ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
+      << "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
+      << ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
+      << ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
+      << ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
+      << ", " << static_cast<int>(a6.a8) << "), (" << static_cast<int>(a7.a0)
+      << ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
+      << ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
+      << ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
+      << ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
+      << "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
+      << ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
+      << ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
+      << ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
+      << ", " << static_cast<int>(a8.a8) << "), (" << static_cast<int>(a9.a0)
+      << ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
+      << ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
+      << ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
+      << ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
+      << "))"
+      << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(4095, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Arguments in FPU registers on arm hardfp and arm64.
+// Struct arguments will exhaust available registers, and leave some empty.
+// The last argument is to test whether arguments are backfilled.
+DART_EXPORT intptr_t TestPassStruct12BytesHomogeneousFloatx6(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(Struct12BytesHomogeneousFloat a0,
+               Struct12BytesHomogeneousFloat a1,
+               Struct12BytesHomogeneousFloat a2,
+               Struct12BytesHomogeneousFloat a3,
+               Struct12BytesHomogeneousFloat a4,
+               Struct12BytesHomogeneousFloat a5)) {
+  Struct12BytesHomogeneousFloat a0;
+  Struct12BytesHomogeneousFloat a1;
+  Struct12BytesHomogeneousFloat a2;
+  Struct12BytesHomogeneousFloat a3;
+  Struct12BytesHomogeneousFloat a4;
+  Struct12BytesHomogeneousFloat a5;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a1.a0 = 4.0;
+  a1.a1 = -5.0;
+  a1.a2 = 6.0;
+  a2.a0 = -7.0;
+  a2.a1 = 8.0;
+  a2.a2 = -9.0;
+  a3.a0 = 10.0;
+  a3.a1 = -11.0;
+  a3.a2 = 12.0;
+  a4.a0 = -13.0;
+  a4.a1 = 14.0;
+  a4.a2 = -15.0;
+  a5.a0 = 16.0;
+  a5.a1 = -17.0;
+  a5.a2 = 18.0;
+
+  std::cout << "Calling TestPassStruct12BytesHomogeneousFloatx6("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << "), ("
+            << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << a3.a2 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << "), (" << a5.a0 << ", " << a5.a1 << ", "
+            << a5.a2 << "))"
+            << ")\n";
+
+  float result = f(a0, a1, a2, a3, a4, a5);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(9.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On Linux x64 argument is transferred on stack because it is over 16 bytes.
+// Arguments in FPU registers on arm hardfp and arm64.
+// 5 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct16BytesHomogeneousFloatx5(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(Struct16BytesHomogeneousFloat a0,
+               Struct16BytesHomogeneousFloat a1,
+               Struct16BytesHomogeneousFloat a2,
+               Struct16BytesHomogeneousFloat a3,
+               Struct16BytesHomogeneousFloat a4)) {
+  Struct16BytesHomogeneousFloat a0;
+  Struct16BytesHomogeneousFloat a1;
+  Struct16BytesHomogeneousFloat a2;
+  Struct16BytesHomogeneousFloat a3;
+  Struct16BytesHomogeneousFloat a4;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8.0;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12.0;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16.0;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20.0;
+
+  std::cout << "Calling TestPassStruct16BytesHomogeneousFloatx5("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
+            << a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
+            << ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
+            << a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << "))"
+            << ")\n";
+
+  float result = f(a0, a1, a2, a3, a4);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(10.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On x64, arguments are split over FP and int registers.
+// On x64, it will exhaust the integer registers with the 6th argument.
+// The rest goes on the stack.
+// On arm, arguments are 8 byte aligned.
+DART_EXPORT intptr_t TestPassStruct16BytesMixedx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct16BytesMixed a0,
+                Struct16BytesMixed a1,
+                Struct16BytesMixed a2,
+                Struct16BytesMixed a3,
+                Struct16BytesMixed a4,
+                Struct16BytesMixed a5,
+                Struct16BytesMixed a6,
+                Struct16BytesMixed a7,
+                Struct16BytesMixed a8,
+                Struct16BytesMixed a9)) {
+  Struct16BytesMixed a0;
+  Struct16BytesMixed a1;
+  Struct16BytesMixed a2;
+  Struct16BytesMixed a3;
+  Struct16BytesMixed a4;
+  Struct16BytesMixed a5;
+  Struct16BytesMixed a6;
+  Struct16BytesMixed a7;
+  Struct16BytesMixed a8;
+  Struct16BytesMixed a9;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+  a1.a0 = -3.0;
+  a1.a1 = 4;
+  a2.a0 = -5.0;
+  a2.a1 = 6;
+  a3.a0 = -7.0;
+  a3.a1 = 8;
+  a4.a0 = -9.0;
+  a4.a1 = 10;
+  a5.a0 = -11.0;
+  a5.a1 = 12;
+  a6.a0 = -13.0;
+  a6.a1 = 14;
+  a7.a0 = -15.0;
+  a7.a1 = 16;
+  a8.a0 = -17.0;
+  a8.a1 = 18;
+  a9.a0 = -19.0;
+  a9.a1 = 20;
+
+  std::cout << "Calling TestPassStruct16BytesMixedx10("
+            << "((" << a0.a0 << ", " << a0.a1 << "), (" << a1.a0 << ", "
+            << a1.a1 << "), (" << a2.a0 << ", " << a2.a1 << "), (" << a3.a0
+            << ", " << a3.a1 << "), (" << a4.a0 << ", " << a4.a1 << "), ("
+            << a5.a0 << ", " << a5.a1 << "), (" << a6.a0 << ", " << a6.a1
+            << "), (" << a7.a0 << ", " << a7.a1 << "), (" << a8.a0 << ", "
+            << a8.a1 << "), (" << a9.a0 << ", " << a9.a1 << "))"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(10.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On x64, arguments are split over FP and int registers.
+// On x64, it will exhaust the integer registers with the 6th argument.
+// The rest goes on the stack.
+// On arm, arguments are 4 byte aligned.
+DART_EXPORT intptr_t TestPassStruct16BytesMixed2x10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(Struct16BytesMixed2 a0,
+               Struct16BytesMixed2 a1,
+               Struct16BytesMixed2 a2,
+               Struct16BytesMixed2 a3,
+               Struct16BytesMixed2 a4,
+               Struct16BytesMixed2 a5,
+               Struct16BytesMixed2 a6,
+               Struct16BytesMixed2 a7,
+               Struct16BytesMixed2 a8,
+               Struct16BytesMixed2 a9)) {
+  Struct16BytesMixed2 a0;
+  Struct16BytesMixed2 a1;
+  Struct16BytesMixed2 a2;
+  Struct16BytesMixed2 a3;
+  Struct16BytesMixed2 a4;
+  Struct16BytesMixed2 a5;
+  Struct16BytesMixed2 a6;
+  Struct16BytesMixed2 a7;
+  Struct16BytesMixed2 a8;
+  Struct16BytesMixed2 a9;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20;
+  a5.a0 = -21.0;
+  a5.a1 = 22.0;
+  a5.a2 = -23.0;
+  a5.a3 = 24;
+  a6.a0 = -25.0;
+  a6.a1 = 26.0;
+  a6.a2 = -27.0;
+  a6.a3 = 28;
+  a7.a0 = -29.0;
+  a7.a1 = 30.0;
+  a7.a2 = -31.0;
+  a7.a3 = 32;
+  a8.a0 = -33.0;
+  a8.a1 = 34.0;
+  a8.a2 = -35.0;
+  a8.a3 = 36;
+  a9.a0 = -37.0;
+  a9.a1 = 38.0;
+  a9.a2 = -39.0;
+  a9.a3 = 40;
+
+  std::cout << "Calling TestPassStruct16BytesMixed2x10("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
+            << a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
+            << ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
+            << a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << "), (" << a5.a0 << ", "
+            << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), (" << a6.a0
+            << ", " << a6.a1 << ", " << a6.a2 << ", " << a6.a3 << "), ("
+            << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
+            << "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
+            << a8.a3 << "), (" << a9.a0 << ", " << a9.a1 << ", " << a9.a2
+            << ", " << a9.a3 << "))"
+            << ")\n";
+
+  float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(20.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Arguments are passed as pointer to copy on arm64.
+// Tests that the memory allocated for copies are rounded up to word size.
+DART_EXPORT intptr_t TestPassStruct17BytesIntx10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct17BytesInt a0,
+                 Struct17BytesInt a1,
+                 Struct17BytesInt a2,
+                 Struct17BytesInt a3,
+                 Struct17BytesInt a4,
+                 Struct17BytesInt a5,
+                 Struct17BytesInt a6,
+                 Struct17BytesInt a7,
+                 Struct17BytesInt a8,
+                 Struct17BytesInt a9)) {
+  Struct17BytesInt a0;
+  Struct17BytesInt a1;
+  Struct17BytesInt a2;
+  Struct17BytesInt a3;
+  Struct17BytesInt a4;
+  Struct17BytesInt a5;
+  Struct17BytesInt a6;
+  Struct17BytesInt a7;
+  Struct17BytesInt a8;
+  Struct17BytesInt a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  std::cout << "Calling TestPassStruct17BytesIntx10("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << static_cast<int>(a0.a2)
+            << "), (" << a1.a0 << ", " << a1.a1 << ", "
+            << static_cast<int>(a1.a2) << "), (" << a2.a0 << ", " << a2.a1
+            << ", " << static_cast<int>(a2.a2) << "), (" << a3.a0 << ", "
+            << a3.a1 << ", " << static_cast<int>(a3.a2) << "), (" << a4.a0
+            << ", " << a4.a1 << ", " << static_cast<int>(a4.a2) << "), ("
+            << a5.a0 << ", " << a5.a1 << ", " << static_cast<int>(a5.a2)
+            << "), (" << a6.a0 << ", " << a6.a1 << ", "
+            << static_cast<int>(a6.a2) << "), (" << a7.a0 << ", " << a7.a1
+            << ", " << static_cast<int>(a7.a2) << "), (" << a8.a0 << ", "
+            << a8.a1 << ", " << static_cast<int>(a8.a2) << "), (" << a9.a0
+            << ", " << a9.a1 << ", " << static_cast<int>(a9.a2) << "))"
+            << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(15, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// The minimum alignment of this struct is only 1 byte based on its fields.
+// Test that the memory backing these structs is extended to the right size.
+//
+DART_EXPORT intptr_t TestPassStruct19BytesHomogeneousUint8x10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(Struct19BytesHomogeneousUint8 a0,
+                 Struct19BytesHomogeneousUint8 a1,
+                 Struct19BytesHomogeneousUint8 a2,
+                 Struct19BytesHomogeneousUint8 a3,
+                 Struct19BytesHomogeneousUint8 a4,
+                 Struct19BytesHomogeneousUint8 a5,
+                 Struct19BytesHomogeneousUint8 a6,
+                 Struct19BytesHomogeneousUint8 a7,
+                 Struct19BytesHomogeneousUint8 a8,
+                 Struct19BytesHomogeneousUint8 a9)) {
+  Struct19BytesHomogeneousUint8 a0;
+  Struct19BytesHomogeneousUint8 a1;
+  Struct19BytesHomogeneousUint8 a2;
+  Struct19BytesHomogeneousUint8 a3;
+  Struct19BytesHomogeneousUint8 a4;
+  Struct19BytesHomogeneousUint8 a5;
+  Struct19BytesHomogeneousUint8 a6;
+  Struct19BytesHomogeneousUint8 a7;
+  Struct19BytesHomogeneousUint8 a8;
+  Struct19BytesHomogeneousUint8 a9;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a0.a9 = 10;
+  a0.a10 = 11;
+  a0.a11 = 12;
+  a0.a12 = 13;
+  a0.a13 = 14;
+  a0.a14 = 15;
+  a0.a15 = 16;
+  a0.a16 = 17;
+  a0.a17 = 18;
+  a0.a18 = 19;
+  a1.a0 = 20;
+  a1.a1 = 21;
+  a1.a2 = 22;
+  a1.a3 = 23;
+  a1.a4 = 24;
+  a1.a5 = 25;
+  a1.a6 = 26;
+  a1.a7 = 27;
+  a1.a8 = 28;
+  a1.a9 = 29;
+  a1.a10 = 30;
+  a1.a11 = 31;
+  a1.a12 = 32;
+  a1.a13 = 33;
+  a1.a14 = 34;
+  a1.a15 = 35;
+  a1.a16 = 36;
+  a1.a17 = 37;
+  a1.a18 = 38;
+  a2.a0 = 39;
+  a2.a1 = 40;
+  a2.a2 = 41;
+  a2.a3 = 42;
+  a2.a4 = 43;
+  a2.a5 = 44;
+  a2.a6 = 45;
+  a2.a7 = 46;
+  a2.a8 = 47;
+  a2.a9 = 48;
+  a2.a10 = 49;
+  a2.a11 = 50;
+  a2.a12 = 51;
+  a2.a13 = 52;
+  a2.a14 = 53;
+  a2.a15 = 54;
+  a2.a16 = 55;
+  a2.a17 = 56;
+  a2.a18 = 57;
+  a3.a0 = 58;
+  a3.a1 = 59;
+  a3.a2 = 60;
+  a3.a3 = 61;
+  a3.a4 = 62;
+  a3.a5 = 63;
+  a3.a6 = 64;
+  a3.a7 = 65;
+  a3.a8 = 66;
+  a3.a9 = 67;
+  a3.a10 = 68;
+  a3.a11 = 69;
+  a3.a12 = 70;
+  a3.a13 = 71;
+  a3.a14 = 72;
+  a3.a15 = 73;
+  a3.a16 = 74;
+  a3.a17 = 75;
+  a3.a18 = 76;
+  a4.a0 = 77;
+  a4.a1 = 78;
+  a4.a2 = 79;
+  a4.a3 = 80;
+  a4.a4 = 81;
+  a4.a5 = 82;
+  a4.a6 = 83;
+  a4.a7 = 84;
+  a4.a8 = 85;
+  a4.a9 = 86;
+  a4.a10 = 87;
+  a4.a11 = 88;
+  a4.a12 = 89;
+  a4.a13 = 90;
+  a4.a14 = 91;
+  a4.a15 = 92;
+  a4.a16 = 93;
+  a4.a17 = 94;
+  a4.a18 = 95;
+  a5.a0 = 96;
+  a5.a1 = 97;
+  a5.a2 = 98;
+  a5.a3 = 99;
+  a5.a4 = 100;
+  a5.a5 = 101;
+  a5.a6 = 102;
+  a5.a7 = 103;
+  a5.a8 = 104;
+  a5.a9 = 105;
+  a5.a10 = 106;
+  a5.a11 = 107;
+  a5.a12 = 108;
+  a5.a13 = 109;
+  a5.a14 = 110;
+  a5.a15 = 111;
+  a5.a16 = 112;
+  a5.a17 = 113;
+  a5.a18 = 114;
+  a6.a0 = 115;
+  a6.a1 = 116;
+  a6.a2 = 117;
+  a6.a3 = 118;
+  a6.a4 = 119;
+  a6.a5 = 120;
+  a6.a6 = 121;
+  a6.a7 = 122;
+  a6.a8 = 123;
+  a6.a9 = 124;
+  a6.a10 = 125;
+  a6.a11 = 126;
+  a6.a12 = 127;
+  a6.a13 = 128;
+  a6.a14 = 129;
+  a6.a15 = 130;
+  a6.a16 = 131;
+  a6.a17 = 132;
+  a6.a18 = 133;
+  a7.a0 = 134;
+  a7.a1 = 135;
+  a7.a2 = 136;
+  a7.a3 = 137;
+  a7.a4 = 138;
+  a7.a5 = 139;
+  a7.a6 = 140;
+  a7.a7 = 141;
+  a7.a8 = 142;
+  a7.a9 = 143;
+  a7.a10 = 144;
+  a7.a11 = 145;
+  a7.a12 = 146;
+  a7.a13 = 147;
+  a7.a14 = 148;
+  a7.a15 = 149;
+  a7.a16 = 150;
+  a7.a17 = 151;
+  a7.a18 = 152;
+  a8.a0 = 153;
+  a8.a1 = 154;
+  a8.a2 = 155;
+  a8.a3 = 156;
+  a8.a4 = 157;
+  a8.a5 = 158;
+  a8.a6 = 159;
+  a8.a7 = 160;
+  a8.a8 = 161;
+  a8.a9 = 162;
+  a8.a10 = 163;
+  a8.a11 = 164;
+  a8.a12 = 165;
+  a8.a13 = 166;
+  a8.a14 = 167;
+  a8.a15 = 168;
+  a8.a16 = 169;
+  a8.a17 = 170;
+  a8.a18 = 171;
+  a9.a0 = 172;
+  a9.a1 = 173;
+  a9.a2 = 174;
+  a9.a3 = 175;
+  a9.a4 = 176;
+  a9.a5 = 177;
+  a9.a6 = 178;
+  a9.a7 = 179;
+  a9.a8 = 180;
+  a9.a9 = 181;
+  a9.a10 = 182;
+  a9.a11 = 183;
+  a9.a12 = 184;
+  a9.a13 = 185;
+  a9.a14 = 186;
+  a9.a15 = 187;
+  a9.a16 = 188;
+  a9.a17 = 189;
+  a9.a18 = 190;
+
+  std::cout
+      << "Calling TestPassStruct19BytesHomogeneousUint8x10("
+      << "((" << static_cast<int>(a0.a0) << ", " << static_cast<int>(a0.a1)
+      << ", " << static_cast<int>(a0.a2) << ", " << static_cast<int>(a0.a3)
+      << ", " << static_cast<int>(a0.a4) << ", " << static_cast<int>(a0.a5)
+      << ", " << static_cast<int>(a0.a6) << ", " << static_cast<int>(a0.a7)
+      << ", " << static_cast<int>(a0.a8) << ", " << static_cast<int>(a0.a9)
+      << ", " << static_cast<int>(a0.a10) << ", " << static_cast<int>(a0.a11)
+      << ", " << static_cast<int>(a0.a12) << ", " << static_cast<int>(a0.a13)
+      << ", " << static_cast<int>(a0.a14) << ", " << static_cast<int>(a0.a15)
+      << ", " << static_cast<int>(a0.a16) << ", " << static_cast<int>(a0.a17)
+      << ", " << static_cast<int>(a0.a18) << "), (" << static_cast<int>(a1.a0)
+      << ", " << static_cast<int>(a1.a1) << ", " << static_cast<int>(a1.a2)
+      << ", " << static_cast<int>(a1.a3) << ", " << static_cast<int>(a1.a4)
+      << ", " << static_cast<int>(a1.a5) << ", " << static_cast<int>(a1.a6)
+      << ", " << static_cast<int>(a1.a7) << ", " << static_cast<int>(a1.a8)
+      << ", " << static_cast<int>(a1.a9) << ", " << static_cast<int>(a1.a10)
+      << ", " << static_cast<int>(a1.a11) << ", " << static_cast<int>(a1.a12)
+      << ", " << static_cast<int>(a1.a13) << ", " << static_cast<int>(a1.a14)
+      << ", " << static_cast<int>(a1.a15) << ", " << static_cast<int>(a1.a16)
+      << ", " << static_cast<int>(a1.a17) << ", " << static_cast<int>(a1.a18)
+      << "), (" << static_cast<int>(a2.a0) << ", " << static_cast<int>(a2.a1)
+      << ", " << static_cast<int>(a2.a2) << ", " << static_cast<int>(a2.a3)
+      << ", " << static_cast<int>(a2.a4) << ", " << static_cast<int>(a2.a5)
+      << ", " << static_cast<int>(a2.a6) << ", " << static_cast<int>(a2.a7)
+      << ", " << static_cast<int>(a2.a8) << ", " << static_cast<int>(a2.a9)
+      << ", " << static_cast<int>(a2.a10) << ", " << static_cast<int>(a2.a11)
+      << ", " << static_cast<int>(a2.a12) << ", " << static_cast<int>(a2.a13)
+      << ", " << static_cast<int>(a2.a14) << ", " << static_cast<int>(a2.a15)
+      << ", " << static_cast<int>(a2.a16) << ", " << static_cast<int>(a2.a17)
+      << ", " << static_cast<int>(a2.a18) << "), (" << static_cast<int>(a3.a0)
+      << ", " << static_cast<int>(a3.a1) << ", " << static_cast<int>(a3.a2)
+      << ", " << static_cast<int>(a3.a3) << ", " << static_cast<int>(a3.a4)
+      << ", " << static_cast<int>(a3.a5) << ", " << static_cast<int>(a3.a6)
+      << ", " << static_cast<int>(a3.a7) << ", " << static_cast<int>(a3.a8)
+      << ", " << static_cast<int>(a3.a9) << ", " << static_cast<int>(a3.a10)
+      << ", " << static_cast<int>(a3.a11) << ", " << static_cast<int>(a3.a12)
+      << ", " << static_cast<int>(a3.a13) << ", " << static_cast<int>(a3.a14)
+      << ", " << static_cast<int>(a3.a15) << ", " << static_cast<int>(a3.a16)
+      << ", " << static_cast<int>(a3.a17) << ", " << static_cast<int>(a3.a18)
+      << "), (" << static_cast<int>(a4.a0) << ", " << static_cast<int>(a4.a1)
+      << ", " << static_cast<int>(a4.a2) << ", " << static_cast<int>(a4.a3)
+      << ", " << static_cast<int>(a4.a4) << ", " << static_cast<int>(a4.a5)
+      << ", " << static_cast<int>(a4.a6) << ", " << static_cast<int>(a4.a7)
+      << ", " << static_cast<int>(a4.a8) << ", " << static_cast<int>(a4.a9)
+      << ", " << static_cast<int>(a4.a10) << ", " << static_cast<int>(a4.a11)
+      << ", " << static_cast<int>(a4.a12) << ", " << static_cast<int>(a4.a13)
+      << ", " << static_cast<int>(a4.a14) << ", " << static_cast<int>(a4.a15)
+      << ", " << static_cast<int>(a4.a16) << ", " << static_cast<int>(a4.a17)
+      << ", " << static_cast<int>(a4.a18) << "), (" << static_cast<int>(a5.a0)
+      << ", " << static_cast<int>(a5.a1) << ", " << static_cast<int>(a5.a2)
+      << ", " << static_cast<int>(a5.a3) << ", " << static_cast<int>(a5.a4)
+      << ", " << static_cast<int>(a5.a5) << ", " << static_cast<int>(a5.a6)
+      << ", " << static_cast<int>(a5.a7) << ", " << static_cast<int>(a5.a8)
+      << ", " << static_cast<int>(a5.a9) << ", " << static_cast<int>(a5.a10)
+      << ", " << static_cast<int>(a5.a11) << ", " << static_cast<int>(a5.a12)
+      << ", " << static_cast<int>(a5.a13) << ", " << static_cast<int>(a5.a14)
+      << ", " << static_cast<int>(a5.a15) << ", " << static_cast<int>(a5.a16)
+      << ", " << static_cast<int>(a5.a17) << ", " << static_cast<int>(a5.a18)
+      << "), (" << static_cast<int>(a6.a0) << ", " << static_cast<int>(a6.a1)
+      << ", " << static_cast<int>(a6.a2) << ", " << static_cast<int>(a6.a3)
+      << ", " << static_cast<int>(a6.a4) << ", " << static_cast<int>(a6.a5)
+      << ", " << static_cast<int>(a6.a6) << ", " << static_cast<int>(a6.a7)
+      << ", " << static_cast<int>(a6.a8) << ", " << static_cast<int>(a6.a9)
+      << ", " << static_cast<int>(a6.a10) << ", " << static_cast<int>(a6.a11)
+      << ", " << static_cast<int>(a6.a12) << ", " << static_cast<int>(a6.a13)
+      << ", " << static_cast<int>(a6.a14) << ", " << static_cast<int>(a6.a15)
+      << ", " << static_cast<int>(a6.a16) << ", " << static_cast<int>(a6.a17)
+      << ", " << static_cast<int>(a6.a18) << "), (" << static_cast<int>(a7.a0)
+      << ", " << static_cast<int>(a7.a1) << ", " << static_cast<int>(a7.a2)
+      << ", " << static_cast<int>(a7.a3) << ", " << static_cast<int>(a7.a4)
+      << ", " << static_cast<int>(a7.a5) << ", " << static_cast<int>(a7.a6)
+      << ", " << static_cast<int>(a7.a7) << ", " << static_cast<int>(a7.a8)
+      << ", " << static_cast<int>(a7.a9) << ", " << static_cast<int>(a7.a10)
+      << ", " << static_cast<int>(a7.a11) << ", " << static_cast<int>(a7.a12)
+      << ", " << static_cast<int>(a7.a13) << ", " << static_cast<int>(a7.a14)
+      << ", " << static_cast<int>(a7.a15) << ", " << static_cast<int>(a7.a16)
+      << ", " << static_cast<int>(a7.a17) << ", " << static_cast<int>(a7.a18)
+      << "), (" << static_cast<int>(a8.a0) << ", " << static_cast<int>(a8.a1)
+      << ", " << static_cast<int>(a8.a2) << ", " << static_cast<int>(a8.a3)
+      << ", " << static_cast<int>(a8.a4) << ", " << static_cast<int>(a8.a5)
+      << ", " << static_cast<int>(a8.a6) << ", " << static_cast<int>(a8.a7)
+      << ", " << static_cast<int>(a8.a8) << ", " << static_cast<int>(a8.a9)
+      << ", " << static_cast<int>(a8.a10) << ", " << static_cast<int>(a8.a11)
+      << ", " << static_cast<int>(a8.a12) << ", " << static_cast<int>(a8.a13)
+      << ", " << static_cast<int>(a8.a14) << ", " << static_cast<int>(a8.a15)
+      << ", " << static_cast<int>(a8.a16) << ", " << static_cast<int>(a8.a17)
+      << ", " << static_cast<int>(a8.a18) << "), (" << static_cast<int>(a9.a0)
+      << ", " << static_cast<int>(a9.a1) << ", " << static_cast<int>(a9.a2)
+      << ", " << static_cast<int>(a9.a3) << ", " << static_cast<int>(a9.a4)
+      << ", " << static_cast<int>(a9.a5) << ", " << static_cast<int>(a9.a6)
+      << ", " << static_cast<int>(a9.a7) << ", " << static_cast<int>(a9.a8)
+      << ", " << static_cast<int>(a9.a9) << ", " << static_cast<int>(a9.a10)
+      << ", " << static_cast<int>(a9.a11) << ", " << static_cast<int>(a9.a12)
+      << ", " << static_cast<int>(a9.a13) << ", " << static_cast<int>(a9.a14)
+      << ", " << static_cast<int>(a9.a15) << ", " << static_cast<int>(a9.a16)
+      << ", " << static_cast<int>(a9.a17) << ", " << static_cast<int>(a9.a18)
+      << "))"
+      << ")\n";
+
+  int64_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(18145, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Argument too big to go into integer registers on arm64.
+// The arguments are passed as pointers to copies.
+// The amount of arguments exhausts the number of integer registers, such that
+// pointers to copies are also passed on the stack.
+DART_EXPORT intptr_t TestPassStruct20BytesHomogeneousInt32x10(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int32_t (*f)(Struct20BytesHomogeneousInt32 a0,
+                 Struct20BytesHomogeneousInt32 a1,
+                 Struct20BytesHomogeneousInt32 a2,
+                 Struct20BytesHomogeneousInt32 a3,
+                 Struct20BytesHomogeneousInt32 a4,
+                 Struct20BytesHomogeneousInt32 a5,
+                 Struct20BytesHomogeneousInt32 a6,
+                 Struct20BytesHomogeneousInt32 a7,
+                 Struct20BytesHomogeneousInt32 a8,
+                 Struct20BytesHomogeneousInt32 a9)) {
+  Struct20BytesHomogeneousInt32 a0;
+  Struct20BytesHomogeneousInt32 a1;
+  Struct20BytesHomogeneousInt32 a2;
+  Struct20BytesHomogeneousInt32 a3;
+  Struct20BytesHomogeneousInt32 a4;
+  Struct20BytesHomogeneousInt32 a5;
+  Struct20BytesHomogeneousInt32 a6;
+  Struct20BytesHomogeneousInt32 a7;
+  Struct20BytesHomogeneousInt32 a8;
+  Struct20BytesHomogeneousInt32 a9;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a0.a3 = 4;
+  a0.a4 = -5;
+  a1.a0 = 6;
+  a1.a1 = -7;
+  a1.a2 = 8;
+  a1.a3 = -9;
+  a1.a4 = 10;
+  a2.a0 = -11;
+  a2.a1 = 12;
+  a2.a2 = -13;
+  a2.a3 = 14;
+  a2.a4 = -15;
+  a3.a0 = 16;
+  a3.a1 = -17;
+  a3.a2 = 18;
+  a3.a3 = -19;
+  a3.a4 = 20;
+  a4.a0 = -21;
+  a4.a1 = 22;
+  a4.a2 = -23;
+  a4.a3 = 24;
+  a4.a4 = -25;
+  a5.a0 = 26;
+  a5.a1 = -27;
+  a5.a2 = 28;
+  a5.a3 = -29;
+  a5.a4 = 30;
+  a6.a0 = -31;
+  a6.a1 = 32;
+  a6.a2 = -33;
+  a6.a3 = 34;
+  a6.a4 = -35;
+  a7.a0 = 36;
+  a7.a1 = -37;
+  a7.a2 = 38;
+  a7.a3 = -39;
+  a7.a4 = 40;
+  a8.a0 = -41;
+  a8.a1 = 42;
+  a8.a2 = -43;
+  a8.a3 = 44;
+  a8.a4 = -45;
+  a9.a0 = 46;
+  a9.a1 = -47;
+  a9.a2 = 48;
+  a9.a3 = -49;
+  a9.a4 = 50;
+
+  std::cout << "Calling TestPassStruct20BytesHomogeneousInt32x10("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << ", "
+            << a1.a2 << ", " << a1.a3 << ", " << a1.a4 << "), (" << a2.a0
+            << ", " << a2.a1 << ", " << a2.a2 << ", " << a2.a3 << ", " << a2.a4
+            << "), (" << a3.a0 << ", " << a3.a1 << ", " << a3.a2 << ", "
+            << a3.a3 << ", " << a3.a4 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << ", " << a4.a4 << "), ("
+            << a5.a0 << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << ", "
+            << a5.a4 << "), (" << a6.a0 << ", " << a6.a1 << ", " << a6.a2
+            << ", " << a6.a3 << ", " << a6.a4 << "), (" << a7.a0 << ", "
+            << a7.a1 << ", " << a7.a2 << ", " << a7.a3 << ", " << a7.a4
+            << "), (" << a8.a0 << ", " << a8.a1 << ", " << a8.a2 << ", "
+            << a8.a3 << ", " << a8.a4 << "), (" << a9.a0 << ", " << a9.a1
+            << ", " << a9.a2 << ", " << a9.a3 << ", " << a9.a4 << "))"
+            << ")\n";
+
+  int32_t result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(25, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Argument too big to go into FPU registers in hardfp and arm64.
+DART_EXPORT intptr_t TestPassStruct20BytesHomogeneousFloat(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(Struct20BytesHomogeneousFloat a0)) {
+  Struct20BytesHomogeneousFloat a0;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+
+  std::cout << "Calling TestPassStruct20BytesHomogeneousFloat("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "))"
+            << ")\n";
+
+  float result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-3.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Arguments in FPU registers on arm64.
+// 5 struct arguments will exhaust available registers.
+DART_EXPORT intptr_t TestPassStruct32BytesHomogeneousDoublex5(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct32BytesHomogeneousDouble a0,
+                Struct32BytesHomogeneousDouble a1,
+                Struct32BytesHomogeneousDouble a2,
+                Struct32BytesHomogeneousDouble a3,
+                Struct32BytesHomogeneousDouble a4)) {
+  Struct32BytesHomogeneousDouble a0;
+  Struct32BytesHomogeneousDouble a1;
+  Struct32BytesHomogeneousDouble a2;
+  Struct32BytesHomogeneousDouble a3;
+  Struct32BytesHomogeneousDouble a4;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8.0;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12.0;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16.0;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20.0;
+
+  std::cout << "Calling TestPassStruct32BytesHomogeneousDoublex5("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << "), (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2 << ", "
+            << a1.a3 << "), (" << a2.a0 << ", " << a2.a1 << ", " << a2.a2
+            << ", " << a2.a3 << "), (" << a3.a0 << ", " << a3.a1 << ", "
+            << a3.a2 << ", " << a3.a3 << "), (" << a4.a0 << ", " << a4.a1
+            << ", " << a4.a2 << ", " << a4.a3 << "))"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(10.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Argument too big to go into FPU registers in arm64.
+DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDouble(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct40BytesHomogeneousDouble a0)) {
+  Struct40BytesHomogeneousDouble a0;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+
+  std::cout << "Calling TestPassStruct40BytesHomogeneousDouble("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "))"
+            << ")\n";
+
+  double result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-3.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test 1kb struct.
+DART_EXPORT intptr_t TestPassStruct1024BytesHomogeneousUint64(
+    // NOLINTNEXTLINE(whitespace/parens)
+    uint64_t (*f)(Struct1024BytesHomogeneousUint64 a0)) {
+  Struct1024BytesHomogeneousUint64 a0;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a0.a9 = 10;
+  a0.a10 = 11;
+  a0.a11 = 12;
+  a0.a12 = 13;
+  a0.a13 = 14;
+  a0.a14 = 15;
+  a0.a15 = 16;
+  a0.a16 = 17;
+  a0.a17 = 18;
+  a0.a18 = 19;
+  a0.a19 = 20;
+  a0.a20 = 21;
+  a0.a21 = 22;
+  a0.a22 = 23;
+  a0.a23 = 24;
+  a0.a24 = 25;
+  a0.a25 = 26;
+  a0.a26 = 27;
+  a0.a27 = 28;
+  a0.a28 = 29;
+  a0.a29 = 30;
+  a0.a30 = 31;
+  a0.a31 = 32;
+  a0.a32 = 33;
+  a0.a33 = 34;
+  a0.a34 = 35;
+  a0.a35 = 36;
+  a0.a36 = 37;
+  a0.a37 = 38;
+  a0.a38 = 39;
+  a0.a39 = 40;
+  a0.a40 = 41;
+  a0.a41 = 42;
+  a0.a42 = 43;
+  a0.a43 = 44;
+  a0.a44 = 45;
+  a0.a45 = 46;
+  a0.a46 = 47;
+  a0.a47 = 48;
+  a0.a48 = 49;
+  a0.a49 = 50;
+  a0.a50 = 51;
+  a0.a51 = 52;
+  a0.a52 = 53;
+  a0.a53 = 54;
+  a0.a54 = 55;
+  a0.a55 = 56;
+  a0.a56 = 57;
+  a0.a57 = 58;
+  a0.a58 = 59;
+  a0.a59 = 60;
+  a0.a60 = 61;
+  a0.a61 = 62;
+  a0.a62 = 63;
+  a0.a63 = 64;
+  a0.a64 = 65;
+  a0.a65 = 66;
+  a0.a66 = 67;
+  a0.a67 = 68;
+  a0.a68 = 69;
+  a0.a69 = 70;
+  a0.a70 = 71;
+  a0.a71 = 72;
+  a0.a72 = 73;
+  a0.a73 = 74;
+  a0.a74 = 75;
+  a0.a75 = 76;
+  a0.a76 = 77;
+  a0.a77 = 78;
+  a0.a78 = 79;
+  a0.a79 = 80;
+  a0.a80 = 81;
+  a0.a81 = 82;
+  a0.a82 = 83;
+  a0.a83 = 84;
+  a0.a84 = 85;
+  a0.a85 = 86;
+  a0.a86 = 87;
+  a0.a87 = 88;
+  a0.a88 = 89;
+  a0.a89 = 90;
+  a0.a90 = 91;
+  a0.a91 = 92;
+  a0.a92 = 93;
+  a0.a93 = 94;
+  a0.a94 = 95;
+  a0.a95 = 96;
+  a0.a96 = 97;
+  a0.a97 = 98;
+  a0.a98 = 99;
+  a0.a99 = 100;
+  a0.a100 = 101;
+  a0.a101 = 102;
+  a0.a102 = 103;
+  a0.a103 = 104;
+  a0.a104 = 105;
+  a0.a105 = 106;
+  a0.a106 = 107;
+  a0.a107 = 108;
+  a0.a108 = 109;
+  a0.a109 = 110;
+  a0.a110 = 111;
+  a0.a111 = 112;
+  a0.a112 = 113;
+  a0.a113 = 114;
+  a0.a114 = 115;
+  a0.a115 = 116;
+  a0.a116 = 117;
+  a0.a117 = 118;
+  a0.a118 = 119;
+  a0.a119 = 120;
+  a0.a120 = 121;
+  a0.a121 = 122;
+  a0.a122 = 123;
+  a0.a123 = 124;
+  a0.a124 = 125;
+  a0.a125 = 126;
+  a0.a126 = 127;
+  a0.a127 = 128;
+
+  std::cout << "Calling TestPassStruct1024BytesHomogeneousUint64("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << ", " << a0.a5 << ", " << a0.a6 << ", " << a0.a7
+            << ", " << a0.a8 << ", " << a0.a9 << ", " << a0.a10 << ", "
+            << a0.a11 << ", " << a0.a12 << ", " << a0.a13 << ", " << a0.a14
+            << ", " << a0.a15 << ", " << a0.a16 << ", " << a0.a17 << ", "
+            << a0.a18 << ", " << a0.a19 << ", " << a0.a20 << ", " << a0.a21
+            << ", " << a0.a22 << ", " << a0.a23 << ", " << a0.a24 << ", "
+            << a0.a25 << ", " << a0.a26 << ", " << a0.a27 << ", " << a0.a28
+            << ", " << a0.a29 << ", " << a0.a30 << ", " << a0.a31 << ", "
+            << a0.a32 << ", " << a0.a33 << ", " << a0.a34 << ", " << a0.a35
+            << ", " << a0.a36 << ", " << a0.a37 << ", " << a0.a38 << ", "
+            << a0.a39 << ", " << a0.a40 << ", " << a0.a41 << ", " << a0.a42
+            << ", " << a0.a43 << ", " << a0.a44 << ", " << a0.a45 << ", "
+            << a0.a46 << ", " << a0.a47 << ", " << a0.a48 << ", " << a0.a49
+            << ", " << a0.a50 << ", " << a0.a51 << ", " << a0.a52 << ", "
+            << a0.a53 << ", " << a0.a54 << ", " << a0.a55 << ", " << a0.a56
+            << ", " << a0.a57 << ", " << a0.a58 << ", " << a0.a59 << ", "
+            << a0.a60 << ", " << a0.a61 << ", " << a0.a62 << ", " << a0.a63
+            << ", " << a0.a64 << ", " << a0.a65 << ", " << a0.a66 << ", "
+            << a0.a67 << ", " << a0.a68 << ", " << a0.a69 << ", " << a0.a70
+            << ", " << a0.a71 << ", " << a0.a72 << ", " << a0.a73 << ", "
+            << a0.a74 << ", " << a0.a75 << ", " << a0.a76 << ", " << a0.a77
+            << ", " << a0.a78 << ", " << a0.a79 << ", " << a0.a80 << ", "
+            << a0.a81 << ", " << a0.a82 << ", " << a0.a83 << ", " << a0.a84
+            << ", " << a0.a85 << ", " << a0.a86 << ", " << a0.a87 << ", "
+            << a0.a88 << ", " << a0.a89 << ", " << a0.a90 << ", " << a0.a91
+            << ", " << a0.a92 << ", " << a0.a93 << ", " << a0.a94 << ", "
+            << a0.a95 << ", " << a0.a96 << ", " << a0.a97 << ", " << a0.a98
+            << ", " << a0.a99 << ", " << a0.a100 << ", " << a0.a101 << ", "
+            << a0.a102 << ", " << a0.a103 << ", " << a0.a104 << ", " << a0.a105
+            << ", " << a0.a106 << ", " << a0.a107 << ", " << a0.a108 << ", "
+            << a0.a109 << ", " << a0.a110 << ", " << a0.a111 << ", " << a0.a112
+            << ", " << a0.a113 << ", " << a0.a114 << ", " << a0.a115 << ", "
+            << a0.a116 << ", " << a0.a117 << ", " << a0.a118 << ", " << a0.a119
+            << ", " << a0.a120 << ", " << a0.a121 << ", " << a0.a122 << ", "
+            << a0.a123 << ", " << a0.a124 << ", " << a0.a125 << ", " << a0.a126
+            << ", " << a0.a127 << "))"
+            << ")\n";
+
+  uint64_t result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(8256, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Tests the alignment of structs in FPU registers and backfilling.
+DART_EXPORT intptr_t TestPassFloatStruct16BytesHomogeneousFloatFloatStruct1(
+    // NOLINTNEXTLINE(whitespace/parens)
+    float (*f)(float a0,
+               Struct16BytesHomogeneousFloat a1,
+               float a2,
+               Struct16BytesHomogeneousFloat a3,
+               float a4,
+               Struct16BytesHomogeneousFloat a5,
+               float a6,
+               Struct16BytesHomogeneousFloat a7,
+               float a8)) {
+  float a0;
+  Struct16BytesHomogeneousFloat a1;
+  float a2;
+  Struct16BytesHomogeneousFloat a3;
+  float a4;
+  Struct16BytesHomogeneousFloat a5;
+  float a6;
+  Struct16BytesHomogeneousFloat a7;
+  float a8;
+
+  a0 = -1.0;
+  a1.a0 = 2.0;
+  a1.a1 = -3.0;
+  a1.a2 = 4.0;
+  a1.a3 = -5.0;
+  a2 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a3.a2 = -9.0;
+  a3.a3 = 10.0;
+  a4 = -11.0;
+  a5.a0 = 12.0;
+  a5.a1 = -13.0;
+  a5.a2 = 14.0;
+  a5.a3 = -15.0;
+  a6 = 16.0;
+  a7.a0 = -17.0;
+  a7.a1 = 18.0;
+  a7.a2 = -19.0;
+  a7.a3 = 20.0;
+  a8 = -21.0;
+
+  std::cout << "Calling TestPassFloatStruct16BytesHomogeneousFloatFloatStruct1("
+            << "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
+            << ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
+            << ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
+            << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
+            << ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
+            << "), " << a8 << ")"
+            << ")\n";
+
+  float result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-11.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Tests the alignment of structs in FPU registers and backfilling.
+DART_EXPORT intptr_t TestPassFloatStruct32BytesHomogeneousDoubleFloatStruct(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(float a0,
+                Struct32BytesHomogeneousDouble a1,
+                float a2,
+                Struct32BytesHomogeneousDouble a3,
+                float a4,
+                Struct32BytesHomogeneousDouble a5,
+                float a6,
+                Struct32BytesHomogeneousDouble a7,
+                float a8)) {
+  float a0;
+  Struct32BytesHomogeneousDouble a1;
+  float a2;
+  Struct32BytesHomogeneousDouble a3;
+  float a4;
+  Struct32BytesHomogeneousDouble a5;
+  float a6;
+  Struct32BytesHomogeneousDouble a7;
+  float a8;
+
+  a0 = -1.0;
+  a1.a0 = 2.0;
+  a1.a1 = -3.0;
+  a1.a2 = 4.0;
+  a1.a3 = -5.0;
+  a2 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a3.a2 = -9.0;
+  a3.a3 = 10.0;
+  a4 = -11.0;
+  a5.a0 = 12.0;
+  a5.a1 = -13.0;
+  a5.a2 = 14.0;
+  a5.a3 = -15.0;
+  a6 = 16.0;
+  a7.a0 = -17.0;
+  a7.a1 = 18.0;
+  a7.a2 = -19.0;
+  a7.a3 = 20.0;
+  a8 = -21.0;
+
+  std::cout << "Calling TestPassFloatStruct32BytesHomogeneousDoubleFloatStruct("
+            << "(" << a0 << ", (" << a1.a0 << ", " << a1.a1 << ", " << a1.a2
+            << ", " << a1.a3 << "), " << a2 << ", (" << a3.a0 << ", " << a3.a1
+            << ", " << a3.a2 << ", " << a3.a3 << "), " << a4 << ", (" << a5.a0
+            << ", " << a5.a1 << ", " << a5.a2 << ", " << a5.a3 << "), " << a6
+            << ", (" << a7.a0 << ", " << a7.a1 << ", " << a7.a2 << ", " << a7.a3
+            << "), " << a8 << ")"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-11.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Tests the alignment of structs in integers registers and on the stack.
+// Arm32 aligns this struct at 8.
+// Also, arm32 allocates the second struct partially in registers, partially
+// on stack.
+// Test backfilling of integer registers.
+DART_EXPORT intptr_t TestPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(int8_t a0,
+                Struct16BytesMixed a1,
+                int8_t a2,
+                Struct16BytesMixed a3,
+                int8_t a4,
+                Struct16BytesMixed a5,
+                int8_t a6,
+                Struct16BytesMixed a7,
+                int8_t a8)) {
+  int8_t a0;
+  Struct16BytesMixed a1;
+  int8_t a2;
+  Struct16BytesMixed a3;
+  int8_t a4;
+  Struct16BytesMixed a5;
+  int8_t a6;
+  Struct16BytesMixed a7;
+  int8_t a8;
+
+  a0 = -1;
+  a1.a0 = 2.0;
+  a1.a1 = -3;
+  a2 = 4;
+  a3.a0 = -5.0;
+  a3.a1 = 6;
+  a4 = -7;
+  a5.a0 = 8.0;
+  a5.a1 = -9;
+  a6 = 10;
+  a7.a0 = -11.0;
+  a7.a1 = 12;
+  a8 = -13;
+
+  std::cout << "Calling TestPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn("
+            << "(" << static_cast<int>(a0) << ", (" << a1.a0 << ", " << a1.a1
+            << "), " << static_cast<int>(a2) << ", (" << a3.a0 << ", " << a3.a1
+            << "), " << static_cast<int>(a4) << ", (" << a5.a0 << ", " << a5.a1
+            << "), " << static_cast<int>(a6) << ", (" << a7.a0 << ", " << a7.a1
+            << "), " << static_cast<int>(a8) << ")"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-7.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+// structs. The rest of the structs will go on the stack.
+// The int will be backfilled into the int register.
+DART_EXPORT intptr_t TestPassDoublex6Struct16BytesMixedx4Int32(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(double a0,
+                double a1,
+                double a2,
+                double a3,
+                double a4,
+                double a5,
+                Struct16BytesMixed a6,
+                Struct16BytesMixed a7,
+                Struct16BytesMixed a8,
+                Struct16BytesMixed a9,
+                int32_t a10)) {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+  double a5;
+  Struct16BytesMixed a6;
+  Struct16BytesMixed a7;
+  Struct16BytesMixed a8;
+  Struct16BytesMixed a9;
+  int32_t a10;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+  a5 = 6.0;
+  a6.a0 = -7.0;
+  a6.a1 = 8;
+  a7.a0 = -9.0;
+  a7.a1 = 10;
+  a8.a0 = -11.0;
+  a8.a1 = 12;
+  a9.a0 = -13.0;
+  a9.a1 = 14;
+  a10 = -15;
+
+  std::cout << "Calling TestPassDoublex6Struct16BytesMixedx4Int32("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0
+            << ", " << a7.a1 << "), (" << a8.a0 << ", " << a8.a1 << "), ("
+            << a9.a0 << ", " << a9.a1 << "), " << a10 << ")"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-8.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On Linux x64, it will exhaust int registers first.
+// The rest of the structs will go on the stack.
+// The double will be backfilled into the xmm register.
+DART_EXPORT intptr_t TestPassInt32x4Struct16BytesMixedx4Double(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(int32_t a0,
+                int32_t a1,
+                int32_t a2,
+                int32_t a3,
+                Struct16BytesMixed a4,
+                Struct16BytesMixed a5,
+                Struct16BytesMixed a6,
+                Struct16BytesMixed a7,
+                double a8)) {
+  int32_t a0;
+  int32_t a1;
+  int32_t a2;
+  int32_t a3;
+  Struct16BytesMixed a4;
+  Struct16BytesMixed a5;
+  Struct16BytesMixed a6;
+  Struct16BytesMixed a7;
+  double a8;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4.a0 = -5.0;
+  a4.a1 = 6;
+  a5.a0 = -7.0;
+  a5.a1 = 8;
+  a6.a0 = -9.0;
+  a6.a1 = 10;
+  a7.a0 = -11.0;
+  a7.a1 = 12;
+  a8 = -13.0;
+
+  std::cout << "Calling TestPassInt32x4Struct16BytesMixedx4Double("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", ("
+            << a4.a0 << ", " << a4.a1 << "), (" << a5.a0 << ", " << a5.a1
+            << "), (" << a6.a0 << ", " << a6.a1 << "), (" << a7.a0 << ", "
+            << a7.a1 << "), " << a8 << ")"
+            << ")\n";
+
+  double result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-7.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On various architectures, first struct is allocated on stack.
+// Check that the other two arguments are allocated on registers.
+DART_EXPORT intptr_t TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo(
+    // NOLINTNEXTLINE(whitespace/parens)
+    double (*f)(Struct40BytesHomogeneousDouble a0,
+                Struct4BytesHomogeneousInt16 a1,
+                Struct8BytesHomogeneousFloat a2)) {
+  Struct40BytesHomogeneousDouble a0;
+  Struct4BytesHomogeneousInt16 a1;
+  Struct8BytesHomogeneousFloat a2;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+  a1.a0 = 6;
+  a1.a1 = -7;
+  a2.a0 = 8.0;
+  a2.a1 = -9.0;
+
+  std::cout << "Calling TestPassStruct40BytesHomogeneousDoubleStruct4BytesHomo("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "), (" << a1.a0 << ", " << a1.a1 << "), ("
+            << a2.a0 << ", " << a2.a1 << "))"
+            << ")\n";
+
+  double result = f(a0, a1, a2);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_APPROX(-5.0, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_APPROX(0.0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_APPROX(0.0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 16 byte int within struct.
+DART_EXPORT intptr_t TestPassStructAlignmentInt16(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(StructAlignmentInt16 a0)) {
+  StructAlignmentInt16 a0;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  std::cout << "Calling TestPassStructAlignmentInt16("
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << "))"
+            << ")\n";
+
+  int64_t result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(-2, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 32 byte int within struct.
+DART_EXPORT intptr_t TestPassStructAlignmentInt32(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(StructAlignmentInt32 a0)) {
+  StructAlignmentInt32 a0;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  std::cout << "Calling TestPassStructAlignmentInt32("
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << "))"
+            << ")\n";
+
+  int64_t result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(-2, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 64 byte int within struct.
+DART_EXPORT intptr_t TestPassStructAlignmentInt64(
+    // NOLINTNEXTLINE(whitespace/parens)
+    int64_t (*f)(StructAlignmentInt64 a0)) {
+  StructAlignmentInt64 a0;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  std::cout << "Calling TestPassStructAlignmentInt64("
+            << "((" << static_cast<int>(a0.a0) << ", " << a0.a1 << ", "
+            << static_cast<int>(a0.a2) << "))"
+            << ")\n";
+
+  int64_t result = f(a0);
+
+  std::cout << "result = " << result << "\n";
+
+  CHECK_EQ(-2, result);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Smallest struct with data.
+DART_EXPORT intptr_t TestReturnStruct1ByteInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct1ByteInt (*f)(int8_t a0)) {
+  int8_t a0;
+
+  a0 = -1;
+
+  std::cout << "Calling TestReturnStruct1ByteInt("
+            << "(" << static_cast<int>(a0) << ")"
+            << ")\n";
+
+  Struct1ByteInt result = f(a0);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result.a0);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result.a0);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Smaller than word size return value on all architectures.
+DART_EXPORT intptr_t TestReturnStruct3BytesInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct3BytesInt (*f)(int16_t a0, int8_t a1)) {
+  int16_t a0;
+  int8_t a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  std::cout << "Calling TestReturnStruct3BytesInt("
+            << "(" << a0 << ", " << static_cast<int>(a1) << ")"
+            << ")\n";
+
+  Struct3BytesInt result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Word size return value on 32 bit architectures..
+DART_EXPORT intptr_t TestReturnStruct4BytesHomogeneousInt16(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct4BytesHomogeneousInt16 (*f)(int16_t a0, int16_t a1)) {
+  int16_t a0;
+  int16_t a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  std::cout << "Calling TestReturnStruct4BytesHomogeneousInt16("
+            << "(" << a0 << ", " << a1 << ")"
+            << ")\n";
+
+  Struct4BytesHomogeneousInt16 result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Non-wordsize return value.
+DART_EXPORT intptr_t TestReturnStruct7BytesInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct7BytesInt (*f)(int32_t a0, int16_t a1, int8_t a2)) {
+  int32_t a0;
+  int16_t a1;
+  int8_t a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStruct7BytesInt("
+            << "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
+            << ")\n";
+
+  Struct7BytesInt result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value in integer registers on many architectures.
+DART_EXPORT intptr_t TestReturnStruct8BytesInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct8BytesInt (*f)(int16_t a0, int16_t a1, int32_t a2)) {
+  int16_t a0;
+  int16_t a1;
+  int32_t a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStruct8BytesInt("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ")"
+            << ")\n";
+
+  Struct8BytesInt result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value in FP registers on many architectures.
+DART_EXPORT intptr_t TestReturnStruct8BytesHomogeneousFloat(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct8BytesHomogeneousFloat (*f)(float a0, float a1)) {
+  float a0;
+  float a1;
+
+  a0 = -1.0;
+  a1 = 2.0;
+
+  std::cout << "Calling TestReturnStruct8BytesHomogeneousFloat("
+            << "(" << a0 << ", " << a1 << ")"
+            << ")\n";
+
+  Struct8BytesHomogeneousFloat result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value split over FP and integer register in x64.
+DART_EXPORT intptr_t TestReturnStruct8BytesMixed(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct8BytesMixed (*f)(float a0, int16_t a1, int16_t a2)) {
+  float a0;
+  int16_t a1;
+  int16_t a2;
+
+  a0 = -1.0;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStruct8BytesMixed("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ")"
+            << ")\n";
+
+  Struct8BytesMixed result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value in two integer registers on x64.
+// The second register only contains a single byte.
+DART_EXPORT intptr_t TestReturnStruct9BytesInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct9BytesInt (*f)(int64_t a0, int8_t a1)) {
+  int64_t a0;
+  int8_t a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  std::cout << "Calling TestReturnStruct9BytesInt("
+            << "(" << a0 << ", " << static_cast<int>(a1) << ")"
+            << ")\n";
+
+  Struct9BytesInt result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << static_cast<int>(result.a1) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// The minimum alignment of this struct is only 1 byte based on its fields.
+// Test that the memory backing these structs is the right size and that
+// dart:ffi trampolines do not write outside this size.
+DART_EXPORT intptr_t TestReturnStruct9BytesHomogeneousUint82(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct9BytesHomogeneousUint82 (*f)(uint8_t a0,
+                                       uint8_t a1,
+                                       uint8_t a2,
+                                       uint8_t a3,
+                                       uint8_t a4,
+                                       uint8_t a5,
+                                       uint8_t a6,
+                                       uint8_t a7,
+                                       uint8_t a8)) {
+  uint8_t a0;
+  uint8_t a1;
+  uint8_t a2;
+  uint8_t a3;
+  uint8_t a4;
+  uint8_t a5;
+  uint8_t a6;
+  uint8_t a7;
+  uint8_t a8;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+
+  std::cout << "Calling TestReturnStruct9BytesHomogeneousUint82("
+            << "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
+            << ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
+            << ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
+            << ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
+            << ", " << static_cast<int>(a8) << ")"
+            << ")\n";
+
+  Struct9BytesHomogeneousUint82 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", "
+            << static_cast<int>(result.a1) << ", "
+            << static_cast<int>(result.a2) << ", "
+            << static_cast<int>(result.a3) << ", "
+            << static_cast<int>(result.a4) << ", "
+            << static_cast<int>(result.a5) << ", "
+            << static_cast<int>(result.a6) << ", "
+            << static_cast<int>(result.a7) << ", "
+            << static_cast<int>(result.a8) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+  CHECK_EQ(a3, result.a3);
+  CHECK_EQ(a4, result.a4);
+  CHECK_EQ(a5, result.a5);
+  CHECK_EQ(a6, result.a6);
+  CHECK_EQ(a7, result.a7);
+  CHECK_EQ(a8, result.a8);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+  CHECK_EQ(0, result.a5);
+  CHECK_EQ(0, result.a6);
+  CHECK_EQ(0, result.a7);
+  CHECK_EQ(0, result.a8);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+  CHECK_EQ(0, result.a5);
+  CHECK_EQ(0, result.a6);
+  CHECK_EQ(0, result.a7);
+  CHECK_EQ(0, result.a8);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value in FPU registers, but does not use all registers on arm hardfp
+// and arm64.
+DART_EXPORT intptr_t TestReturnStruct12BytesHomogeneousFloat(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct12BytesHomogeneousFloat (*f)(float a0, float a1, float a2)) {
+  float a0;
+  float a1;
+  float a2;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+
+  std::cout << "Calling TestReturnStruct12BytesHomogeneousFloat("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ")"
+            << ")\n";
+
+  Struct12BytesHomogeneousFloat result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+  CHECK_APPROX(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value in FPU registers on arm hardfp and arm64.
+DART_EXPORT intptr_t TestReturnStruct16BytesHomogeneousFloat(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct16BytesHomogeneousFloat (
+        *f)(float a0, float a1, float a2, float a3)) {
+  float a0;
+  float a1;
+  float a2;
+  float a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+
+  std::cout << "Calling TestReturnStruct16BytesHomogeneousFloat("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
+            << ")\n";
+
+  Struct16BytesHomogeneousFloat result = f(a0, a1, a2, a3);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+  CHECK_APPROX(a2, result.a2);
+  CHECK_APPROX(a3, result.a3);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value split over FP and integer register in x64.
+DART_EXPORT intptr_t TestReturnStruct16BytesMixed(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct16BytesMixed (*f)(double a0, int64_t a1)) {
+  double a0;
+  int64_t a1;
+
+  a0 = -1.0;
+  a1 = 2;
+
+  std::cout << "Calling TestReturnStruct16BytesMixed("
+            << "(" << a0 << ", " << a1 << ")"
+            << ")\n";
+
+  Struct16BytesMixed result = f(a0, a1);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_EQ(0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value split over FP and integer register in x64.
+// The integer register contains half float half int.
+DART_EXPORT intptr_t TestReturnStruct16BytesMixed2(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct16BytesMixed2 (*f)(float a0, float a1, float a2, int32_t a3)) {
+  float a0;
+  float a1;
+  float a2;
+  int32_t a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4;
+
+  std::cout << "Calling TestReturnStruct16BytesMixed2("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
+            << ")\n";
+
+  Struct16BytesMixed2 result = f(a0, a1, a2, a3);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+  CHECK_APPROX(a2, result.a2);
+  CHECK_EQ(a3, result.a3);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_EQ(0, result.a3);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_EQ(0, result.a3);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Rerturn value returned in preallocated space passed by pointer on most ABIs.
+// Is non word size on purpose, to test that structs are rounded up to word size
+// on all ABIs.
+DART_EXPORT intptr_t TestReturnStruct17BytesInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct17BytesInt (*f)(int64_t a0, int64_t a1, int8_t a2)) {
+  int64_t a0;
+  int64_t a1;
+  int8_t a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStruct17BytesInt("
+            << "(" << a0 << ", " << a1 << ", " << static_cast<int>(a2) << ")"
+            << ")\n";
+
+  Struct17BytesInt result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// The minimum alignment of this struct is only 1 byte based on its fields.
+// Test that the memory backing these structs is the right size and that
+// dart:ffi trampolines do not write outside this size.
+DART_EXPORT intptr_t TestReturnStruct19BytesHomogeneousUint8(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct19BytesHomogeneousUint8 (*f)(uint8_t a0,
+                                       uint8_t a1,
+                                       uint8_t a2,
+                                       uint8_t a3,
+                                       uint8_t a4,
+                                       uint8_t a5,
+                                       uint8_t a6,
+                                       uint8_t a7,
+                                       uint8_t a8,
+                                       uint8_t a9,
+                                       uint8_t a10,
+                                       uint8_t a11,
+                                       uint8_t a12,
+                                       uint8_t a13,
+                                       uint8_t a14,
+                                       uint8_t a15,
+                                       uint8_t a16,
+                                       uint8_t a17,
+                                       uint8_t a18)) {
+  uint8_t a0;
+  uint8_t a1;
+  uint8_t a2;
+  uint8_t a3;
+  uint8_t a4;
+  uint8_t a5;
+  uint8_t a6;
+  uint8_t a7;
+  uint8_t a8;
+  uint8_t a9;
+  uint8_t a10;
+  uint8_t a11;
+  uint8_t a12;
+  uint8_t a13;
+  uint8_t a14;
+  uint8_t a15;
+  uint8_t a16;
+  uint8_t a17;
+  uint8_t a18;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+  a9 = 10;
+  a10 = 11;
+  a11 = 12;
+  a12 = 13;
+  a13 = 14;
+  a14 = 15;
+  a15 = 16;
+  a16 = 17;
+  a17 = 18;
+  a18 = 19;
+
+  std::cout << "Calling TestReturnStruct19BytesHomogeneousUint8("
+            << "(" << static_cast<int>(a0) << ", " << static_cast<int>(a1)
+            << ", " << static_cast<int>(a2) << ", " << static_cast<int>(a3)
+            << ", " << static_cast<int>(a4) << ", " << static_cast<int>(a5)
+            << ", " << static_cast<int>(a6) << ", " << static_cast<int>(a7)
+            << ", " << static_cast<int>(a8) << ", " << static_cast<int>(a9)
+            << ", " << static_cast<int>(a10) << ", " << static_cast<int>(a11)
+            << ", " << static_cast<int>(a12) << ", " << static_cast<int>(a13)
+            << ", " << static_cast<int>(a14) << ", " << static_cast<int>(a15)
+            << ", " << static_cast<int>(a16) << ", " << static_cast<int>(a17)
+            << ", " << static_cast<int>(a18) << ")"
+            << ")\n";
+
+  Struct19BytesHomogeneousUint8 result =
+      f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
+        a16, a17, a18);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", "
+            << static_cast<int>(result.a1) << ", "
+            << static_cast<int>(result.a2) << ", "
+            << static_cast<int>(result.a3) << ", "
+            << static_cast<int>(result.a4) << ", "
+            << static_cast<int>(result.a5) << ", "
+            << static_cast<int>(result.a6) << ", "
+            << static_cast<int>(result.a7) << ", "
+            << static_cast<int>(result.a8) << ", "
+            << static_cast<int>(result.a9) << ", "
+            << static_cast<int>(result.a10) << ", "
+            << static_cast<int>(result.a11) << ", "
+            << static_cast<int>(result.a12) << ", "
+            << static_cast<int>(result.a13) << ", "
+            << static_cast<int>(result.a14) << ", "
+            << static_cast<int>(result.a15) << ", "
+            << static_cast<int>(result.a16) << ", "
+            << static_cast<int>(result.a17) << ", "
+            << static_cast<int>(result.a18) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+  CHECK_EQ(a3, result.a3);
+  CHECK_EQ(a4, result.a4);
+  CHECK_EQ(a5, result.a5);
+  CHECK_EQ(a6, result.a6);
+  CHECK_EQ(a7, result.a7);
+  CHECK_EQ(a8, result.a8);
+  CHECK_EQ(a9, result.a9);
+  CHECK_EQ(a10, result.a10);
+  CHECK_EQ(a11, result.a11);
+  CHECK_EQ(a12, result.a12);
+  CHECK_EQ(a13, result.a13);
+  CHECK_EQ(a14, result.a14);
+  CHECK_EQ(a15, result.a15);
+  CHECK_EQ(a16, result.a16);
+  CHECK_EQ(a17, result.a17);
+  CHECK_EQ(a18, result.a18);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
+             a15, a16, a17, a18);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+  CHECK_EQ(0, result.a5);
+  CHECK_EQ(0, result.a6);
+  CHECK_EQ(0, result.a7);
+  CHECK_EQ(0, result.a8);
+  CHECK_EQ(0, result.a9);
+  CHECK_EQ(0, result.a10);
+  CHECK_EQ(0, result.a11);
+  CHECK_EQ(0, result.a12);
+  CHECK_EQ(0, result.a13);
+  CHECK_EQ(0, result.a14);
+  CHECK_EQ(0, result.a15);
+  CHECK_EQ(0, result.a16);
+  CHECK_EQ(0, result.a17);
+  CHECK_EQ(0, result.a18);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14,
+             a15, a16, a17, a18);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+  CHECK_EQ(0, result.a5);
+  CHECK_EQ(0, result.a6);
+  CHECK_EQ(0, result.a7);
+  CHECK_EQ(0, result.a8);
+  CHECK_EQ(0, result.a9);
+  CHECK_EQ(0, result.a10);
+  CHECK_EQ(0, result.a11);
+  CHECK_EQ(0, result.a12);
+  CHECK_EQ(0, result.a13);
+  CHECK_EQ(0, result.a14);
+  CHECK_EQ(0, result.a15);
+  CHECK_EQ(0, result.a16);
+  CHECK_EQ(0, result.a17);
+  CHECK_EQ(0, result.a18);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value too big to go in cpu registers on arm64.
+DART_EXPORT intptr_t TestReturnStruct20BytesHomogeneousInt32(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct20BytesHomogeneousInt32 (
+        *f)(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4)) {
+  int32_t a0;
+  int32_t a1;
+  int32_t a2;
+  int32_t a3;
+  int32_t a4;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+
+  std::cout << "Calling TestReturnStruct20BytesHomogeneousInt32("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ")"
+            << ")\n";
+
+  Struct20BytesHomogeneousInt32 result = f(a0, a1, a2, a3, a4);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+  CHECK_EQ(a3, result.a3);
+  CHECK_EQ(a4, result.a4);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
+DART_EXPORT intptr_t TestReturnStruct20BytesHomogeneousFloat(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct20BytesHomogeneousFloat (
+        *f)(float a0, float a1, float a2, float a3, float a4)) {
+  float a0;
+  float a1;
+  float a2;
+  float a3;
+  float a4;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+
+  std::cout << "Calling TestReturnStruct20BytesHomogeneousFloat("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ")"
+            << ")\n";
+
+  Struct20BytesHomogeneousFloat result = f(a0, a1, a2, a3, a4);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+  CHECK_APPROX(a2, result.a2);
+  CHECK_APPROX(a3, result.a3);
+  CHECK_APPROX(a4, result.a4);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+  CHECK_APPROX(0.0, result.a4);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+  CHECK_APPROX(0.0, result.a4);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value in FPU registers on arm64.
+DART_EXPORT intptr_t TestReturnStruct32BytesHomogeneousDouble(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct32BytesHomogeneousDouble (
+        *f)(double a0, double a1, double a2, double a3)) {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+
+  std::cout << "Calling TestReturnStruct32BytesHomogeneousDouble("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ")"
+            << ")\n";
+
+  Struct32BytesHomogeneousDouble result = f(a0, a1, a2, a3);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+  CHECK_APPROX(a2, result.a2);
+  CHECK_APPROX(a3, result.a3);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Return value too big to go in FPU registers on arm64.
+DART_EXPORT intptr_t TestReturnStruct40BytesHomogeneousDouble(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct40BytesHomogeneousDouble (
+        *f)(double a0, double a1, double a2, double a3, double a4)) {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+
+  std::cout << "Calling TestReturnStruct40BytesHomogeneousDouble("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ")"
+            << ")\n";
+
+  Struct40BytesHomogeneousDouble result = f(a0, a1, a2, a3, a4);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0, result.a0);
+  CHECK_APPROX(a1, result.a1);
+  CHECK_APPROX(a2, result.a2);
+  CHECK_APPROX(a3, result.a3);
+  CHECK_APPROX(a4, result.a4);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+  CHECK_APPROX(0.0, result.a4);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+  CHECK_APPROX(0.0, result.a2);
+  CHECK_APPROX(0.0, result.a3);
+  CHECK_APPROX(0.0, result.a4);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test 1kb struct.
+DART_EXPORT intptr_t TestReturnStruct1024BytesHomogeneousUint64(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct1024BytesHomogeneousUint64 (*f)(uint64_t a0,
+                                          uint64_t a1,
+                                          uint64_t a2,
+                                          uint64_t a3,
+                                          uint64_t a4,
+                                          uint64_t a5,
+                                          uint64_t a6,
+                                          uint64_t a7,
+                                          uint64_t a8,
+                                          uint64_t a9,
+                                          uint64_t a10,
+                                          uint64_t a11,
+                                          uint64_t a12,
+                                          uint64_t a13,
+                                          uint64_t a14,
+                                          uint64_t a15,
+                                          uint64_t a16,
+                                          uint64_t a17,
+                                          uint64_t a18,
+                                          uint64_t a19,
+                                          uint64_t a20,
+                                          uint64_t a21,
+                                          uint64_t a22,
+                                          uint64_t a23,
+                                          uint64_t a24,
+                                          uint64_t a25,
+                                          uint64_t a26,
+                                          uint64_t a27,
+                                          uint64_t a28,
+                                          uint64_t a29,
+                                          uint64_t a30,
+                                          uint64_t a31,
+                                          uint64_t a32,
+                                          uint64_t a33,
+                                          uint64_t a34,
+                                          uint64_t a35,
+                                          uint64_t a36,
+                                          uint64_t a37,
+                                          uint64_t a38,
+                                          uint64_t a39,
+                                          uint64_t a40,
+                                          uint64_t a41,
+                                          uint64_t a42,
+                                          uint64_t a43,
+                                          uint64_t a44,
+                                          uint64_t a45,
+                                          uint64_t a46,
+                                          uint64_t a47,
+                                          uint64_t a48,
+                                          uint64_t a49,
+                                          uint64_t a50,
+                                          uint64_t a51,
+                                          uint64_t a52,
+                                          uint64_t a53,
+                                          uint64_t a54,
+                                          uint64_t a55,
+                                          uint64_t a56,
+                                          uint64_t a57,
+                                          uint64_t a58,
+                                          uint64_t a59,
+                                          uint64_t a60,
+                                          uint64_t a61,
+                                          uint64_t a62,
+                                          uint64_t a63,
+                                          uint64_t a64,
+                                          uint64_t a65,
+                                          uint64_t a66,
+                                          uint64_t a67,
+                                          uint64_t a68,
+                                          uint64_t a69,
+                                          uint64_t a70,
+                                          uint64_t a71,
+                                          uint64_t a72,
+                                          uint64_t a73,
+                                          uint64_t a74,
+                                          uint64_t a75,
+                                          uint64_t a76,
+                                          uint64_t a77,
+                                          uint64_t a78,
+                                          uint64_t a79,
+                                          uint64_t a80,
+                                          uint64_t a81,
+                                          uint64_t a82,
+                                          uint64_t a83,
+                                          uint64_t a84,
+                                          uint64_t a85,
+                                          uint64_t a86,
+                                          uint64_t a87,
+                                          uint64_t a88,
+                                          uint64_t a89,
+                                          uint64_t a90,
+                                          uint64_t a91,
+                                          uint64_t a92,
+                                          uint64_t a93,
+                                          uint64_t a94,
+                                          uint64_t a95,
+                                          uint64_t a96,
+                                          uint64_t a97,
+                                          uint64_t a98,
+                                          uint64_t a99,
+                                          uint64_t a100,
+                                          uint64_t a101,
+                                          uint64_t a102,
+                                          uint64_t a103,
+                                          uint64_t a104,
+                                          uint64_t a105,
+                                          uint64_t a106,
+                                          uint64_t a107,
+                                          uint64_t a108,
+                                          uint64_t a109,
+                                          uint64_t a110,
+                                          uint64_t a111,
+                                          uint64_t a112,
+                                          uint64_t a113,
+                                          uint64_t a114,
+                                          uint64_t a115,
+                                          uint64_t a116,
+                                          uint64_t a117,
+                                          uint64_t a118,
+                                          uint64_t a119,
+                                          uint64_t a120,
+                                          uint64_t a121,
+                                          uint64_t a122,
+                                          uint64_t a123,
+                                          uint64_t a124,
+                                          uint64_t a125,
+                                          uint64_t a126,
+                                          uint64_t a127)) {
+  uint64_t a0;
+  uint64_t a1;
+  uint64_t a2;
+  uint64_t a3;
+  uint64_t a4;
+  uint64_t a5;
+  uint64_t a6;
+  uint64_t a7;
+  uint64_t a8;
+  uint64_t a9;
+  uint64_t a10;
+  uint64_t a11;
+  uint64_t a12;
+  uint64_t a13;
+  uint64_t a14;
+  uint64_t a15;
+  uint64_t a16;
+  uint64_t a17;
+  uint64_t a18;
+  uint64_t a19;
+  uint64_t a20;
+  uint64_t a21;
+  uint64_t a22;
+  uint64_t a23;
+  uint64_t a24;
+  uint64_t a25;
+  uint64_t a26;
+  uint64_t a27;
+  uint64_t a28;
+  uint64_t a29;
+  uint64_t a30;
+  uint64_t a31;
+  uint64_t a32;
+  uint64_t a33;
+  uint64_t a34;
+  uint64_t a35;
+  uint64_t a36;
+  uint64_t a37;
+  uint64_t a38;
+  uint64_t a39;
+  uint64_t a40;
+  uint64_t a41;
+  uint64_t a42;
+  uint64_t a43;
+  uint64_t a44;
+  uint64_t a45;
+  uint64_t a46;
+  uint64_t a47;
+  uint64_t a48;
+  uint64_t a49;
+  uint64_t a50;
+  uint64_t a51;
+  uint64_t a52;
+  uint64_t a53;
+  uint64_t a54;
+  uint64_t a55;
+  uint64_t a56;
+  uint64_t a57;
+  uint64_t a58;
+  uint64_t a59;
+  uint64_t a60;
+  uint64_t a61;
+  uint64_t a62;
+  uint64_t a63;
+  uint64_t a64;
+  uint64_t a65;
+  uint64_t a66;
+  uint64_t a67;
+  uint64_t a68;
+  uint64_t a69;
+  uint64_t a70;
+  uint64_t a71;
+  uint64_t a72;
+  uint64_t a73;
+  uint64_t a74;
+  uint64_t a75;
+  uint64_t a76;
+  uint64_t a77;
+  uint64_t a78;
+  uint64_t a79;
+  uint64_t a80;
+  uint64_t a81;
+  uint64_t a82;
+  uint64_t a83;
+  uint64_t a84;
+  uint64_t a85;
+  uint64_t a86;
+  uint64_t a87;
+  uint64_t a88;
+  uint64_t a89;
+  uint64_t a90;
+  uint64_t a91;
+  uint64_t a92;
+  uint64_t a93;
+  uint64_t a94;
+  uint64_t a95;
+  uint64_t a96;
+  uint64_t a97;
+  uint64_t a98;
+  uint64_t a99;
+  uint64_t a100;
+  uint64_t a101;
+  uint64_t a102;
+  uint64_t a103;
+  uint64_t a104;
+  uint64_t a105;
+  uint64_t a106;
+  uint64_t a107;
+  uint64_t a108;
+  uint64_t a109;
+  uint64_t a110;
+  uint64_t a111;
+  uint64_t a112;
+  uint64_t a113;
+  uint64_t a114;
+  uint64_t a115;
+  uint64_t a116;
+  uint64_t a117;
+  uint64_t a118;
+  uint64_t a119;
+  uint64_t a120;
+  uint64_t a121;
+  uint64_t a122;
+  uint64_t a123;
+  uint64_t a124;
+  uint64_t a125;
+  uint64_t a126;
+  uint64_t a127;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+  a9 = 10;
+  a10 = 11;
+  a11 = 12;
+  a12 = 13;
+  a13 = 14;
+  a14 = 15;
+  a15 = 16;
+  a16 = 17;
+  a17 = 18;
+  a18 = 19;
+  a19 = 20;
+  a20 = 21;
+  a21 = 22;
+  a22 = 23;
+  a23 = 24;
+  a24 = 25;
+  a25 = 26;
+  a26 = 27;
+  a27 = 28;
+  a28 = 29;
+  a29 = 30;
+  a30 = 31;
+  a31 = 32;
+  a32 = 33;
+  a33 = 34;
+  a34 = 35;
+  a35 = 36;
+  a36 = 37;
+  a37 = 38;
+  a38 = 39;
+  a39 = 40;
+  a40 = 41;
+  a41 = 42;
+  a42 = 43;
+  a43 = 44;
+  a44 = 45;
+  a45 = 46;
+  a46 = 47;
+  a47 = 48;
+  a48 = 49;
+  a49 = 50;
+  a50 = 51;
+  a51 = 52;
+  a52 = 53;
+  a53 = 54;
+  a54 = 55;
+  a55 = 56;
+  a56 = 57;
+  a57 = 58;
+  a58 = 59;
+  a59 = 60;
+  a60 = 61;
+  a61 = 62;
+  a62 = 63;
+  a63 = 64;
+  a64 = 65;
+  a65 = 66;
+  a66 = 67;
+  a67 = 68;
+  a68 = 69;
+  a69 = 70;
+  a70 = 71;
+  a71 = 72;
+  a72 = 73;
+  a73 = 74;
+  a74 = 75;
+  a75 = 76;
+  a76 = 77;
+  a77 = 78;
+  a78 = 79;
+  a79 = 80;
+  a80 = 81;
+  a81 = 82;
+  a82 = 83;
+  a83 = 84;
+  a84 = 85;
+  a85 = 86;
+  a86 = 87;
+  a87 = 88;
+  a88 = 89;
+  a89 = 90;
+  a90 = 91;
+  a91 = 92;
+  a92 = 93;
+  a93 = 94;
+  a94 = 95;
+  a95 = 96;
+  a96 = 97;
+  a97 = 98;
+  a98 = 99;
+  a99 = 100;
+  a100 = 101;
+  a101 = 102;
+  a102 = 103;
+  a103 = 104;
+  a104 = 105;
+  a105 = 106;
+  a106 = 107;
+  a107 = 108;
+  a108 = 109;
+  a109 = 110;
+  a110 = 111;
+  a111 = 112;
+  a112 = 113;
+  a113 = 114;
+  a114 = 115;
+  a115 = 116;
+  a116 = 117;
+  a117 = 118;
+  a118 = 119;
+  a119 = 120;
+  a120 = 121;
+  a121 = 122;
+  a122 = 123;
+  a123 = 124;
+  a124 = 125;
+  a125 = 126;
+  a126 = 127;
+  a127 = 128;
+
+  std::cout << "Calling TestReturnStruct1024BytesHomogeneousUint64("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", " << a6 << ", " << a7 << ", " << a8 << ", "
+            << a9 << ", " << a10 << ", " << a11 << ", " << a12 << ", " << a13
+            << ", " << a14 << ", " << a15 << ", " << a16 << ", " << a17 << ", "
+            << a18 << ", " << a19 << ", " << a20 << ", " << a21 << ", " << a22
+            << ", " << a23 << ", " << a24 << ", " << a25 << ", " << a26 << ", "
+            << a27 << ", " << a28 << ", " << a29 << ", " << a30 << ", " << a31
+            << ", " << a32 << ", " << a33 << ", " << a34 << ", " << a35 << ", "
+            << a36 << ", " << a37 << ", " << a38 << ", " << a39 << ", " << a40
+            << ", " << a41 << ", " << a42 << ", " << a43 << ", " << a44 << ", "
+            << a45 << ", " << a46 << ", " << a47 << ", " << a48 << ", " << a49
+            << ", " << a50 << ", " << a51 << ", " << a52 << ", " << a53 << ", "
+            << a54 << ", " << a55 << ", " << a56 << ", " << a57 << ", " << a58
+            << ", " << a59 << ", " << a60 << ", " << a61 << ", " << a62 << ", "
+            << a63 << ", " << a64 << ", " << a65 << ", " << a66 << ", " << a67
+            << ", " << a68 << ", " << a69 << ", " << a70 << ", " << a71 << ", "
+            << a72 << ", " << a73 << ", " << a74 << ", " << a75 << ", " << a76
+            << ", " << a77 << ", " << a78 << ", " << a79 << ", " << a80 << ", "
+            << a81 << ", " << a82 << ", " << a83 << ", " << a84 << ", " << a85
+            << ", " << a86 << ", " << a87 << ", " << a88 << ", " << a89 << ", "
+            << a90 << ", " << a91 << ", " << a92 << ", " << a93 << ", " << a94
+            << ", " << a95 << ", " << a96 << ", " << a97 << ", " << a98 << ", "
+            << a99 << ", " << a100 << ", " << a101 << ", " << a102 << ", "
+            << a103 << ", " << a104 << ", " << a105 << ", " << a106 << ", "
+            << a107 << ", " << a108 << ", " << a109 << ", " << a110 << ", "
+            << a111 << ", " << a112 << ", " << a113 << ", " << a114 << ", "
+            << a115 << ", " << a116 << ", " << a117 << ", " << a118 << ", "
+            << a119 << ", " << a120 << ", " << a121 << ", " << a122 << ", "
+            << a123 << ", " << a124 << ", " << a125 << ", " << a126 << ", "
+            << a127 << ")"
+            << ")\n";
+
+  Struct1024BytesHomogeneousUint64 result = f(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
+      a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31,
+      a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46,
+      a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61,
+      a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76,
+      a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91,
+      a92, a93, a94, a95, a96, a97, a98, a99, a100, a101, a102, a103, a104,
+      a105, a106, a107, a108, a109, a110, a111, a112, a113, a114, a115, a116,
+      a117, a118, a119, a120, a121, a122, a123, a124, a125, a126, a127);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ", " << result.a5
+            << ", " << result.a6 << ", " << result.a7 << ", " << result.a8
+            << ", " << result.a9 << ", " << result.a10 << ", " << result.a11
+            << ", " << result.a12 << ", " << result.a13 << ", " << result.a14
+            << ", " << result.a15 << ", " << result.a16 << ", " << result.a17
+            << ", " << result.a18 << ", " << result.a19 << ", " << result.a20
+            << ", " << result.a21 << ", " << result.a22 << ", " << result.a23
+            << ", " << result.a24 << ", " << result.a25 << ", " << result.a26
+            << ", " << result.a27 << ", " << result.a28 << ", " << result.a29
+            << ", " << result.a30 << ", " << result.a31 << ", " << result.a32
+            << ", " << result.a33 << ", " << result.a34 << ", " << result.a35
+            << ", " << result.a36 << ", " << result.a37 << ", " << result.a38
+            << ", " << result.a39 << ", " << result.a40 << ", " << result.a41
+            << ", " << result.a42 << ", " << result.a43 << ", " << result.a44
+            << ", " << result.a45 << ", " << result.a46 << ", " << result.a47
+            << ", " << result.a48 << ", " << result.a49 << ", " << result.a50
+            << ", " << result.a51 << ", " << result.a52 << ", " << result.a53
+            << ", " << result.a54 << ", " << result.a55 << ", " << result.a56
+            << ", " << result.a57 << ", " << result.a58 << ", " << result.a59
+            << ", " << result.a60 << ", " << result.a61 << ", " << result.a62
+            << ", " << result.a63 << ", " << result.a64 << ", " << result.a65
+            << ", " << result.a66 << ", " << result.a67 << ", " << result.a68
+            << ", " << result.a69 << ", " << result.a70 << ", " << result.a71
+            << ", " << result.a72 << ", " << result.a73 << ", " << result.a74
+            << ", " << result.a75 << ", " << result.a76 << ", " << result.a77
+            << ", " << result.a78 << ", " << result.a79 << ", " << result.a80
+            << ", " << result.a81 << ", " << result.a82 << ", " << result.a83
+            << ", " << result.a84 << ", " << result.a85 << ", " << result.a86
+            << ", " << result.a87 << ", " << result.a88 << ", " << result.a89
+            << ", " << result.a90 << ", " << result.a91 << ", " << result.a92
+            << ", " << result.a93 << ", " << result.a94 << ", " << result.a95
+            << ", " << result.a96 << ", " << result.a97 << ", " << result.a98
+            << ", " << result.a99 << ", " << result.a100 << ", " << result.a101
+            << ", " << result.a102 << ", " << result.a103 << ", " << result.a104
+            << ", " << result.a105 << ", " << result.a106 << ", " << result.a107
+            << ", " << result.a108 << ", " << result.a109 << ", " << result.a110
+            << ", " << result.a111 << ", " << result.a112 << ", " << result.a113
+            << ", " << result.a114 << ", " << result.a115 << ", " << result.a116
+            << ", " << result.a117 << ", " << result.a118 << ", " << result.a119
+            << ", " << result.a120 << ", " << result.a121 << ", " << result.a122
+            << ", " << result.a123 << ", " << result.a124 << ", " << result.a125
+            << ", " << result.a126 << ", " << result.a127 << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+  CHECK_EQ(a3, result.a3);
+  CHECK_EQ(a4, result.a4);
+  CHECK_EQ(a5, result.a5);
+  CHECK_EQ(a6, result.a6);
+  CHECK_EQ(a7, result.a7);
+  CHECK_EQ(a8, result.a8);
+  CHECK_EQ(a9, result.a9);
+  CHECK_EQ(a10, result.a10);
+  CHECK_EQ(a11, result.a11);
+  CHECK_EQ(a12, result.a12);
+  CHECK_EQ(a13, result.a13);
+  CHECK_EQ(a14, result.a14);
+  CHECK_EQ(a15, result.a15);
+  CHECK_EQ(a16, result.a16);
+  CHECK_EQ(a17, result.a17);
+  CHECK_EQ(a18, result.a18);
+  CHECK_EQ(a19, result.a19);
+  CHECK_EQ(a20, result.a20);
+  CHECK_EQ(a21, result.a21);
+  CHECK_EQ(a22, result.a22);
+  CHECK_EQ(a23, result.a23);
+  CHECK_EQ(a24, result.a24);
+  CHECK_EQ(a25, result.a25);
+  CHECK_EQ(a26, result.a26);
+  CHECK_EQ(a27, result.a27);
+  CHECK_EQ(a28, result.a28);
+  CHECK_EQ(a29, result.a29);
+  CHECK_EQ(a30, result.a30);
+  CHECK_EQ(a31, result.a31);
+  CHECK_EQ(a32, result.a32);
+  CHECK_EQ(a33, result.a33);
+  CHECK_EQ(a34, result.a34);
+  CHECK_EQ(a35, result.a35);
+  CHECK_EQ(a36, result.a36);
+  CHECK_EQ(a37, result.a37);
+  CHECK_EQ(a38, result.a38);
+  CHECK_EQ(a39, result.a39);
+  CHECK_EQ(a40, result.a40);
+  CHECK_EQ(a41, result.a41);
+  CHECK_EQ(a42, result.a42);
+  CHECK_EQ(a43, result.a43);
+  CHECK_EQ(a44, result.a44);
+  CHECK_EQ(a45, result.a45);
+  CHECK_EQ(a46, result.a46);
+  CHECK_EQ(a47, result.a47);
+  CHECK_EQ(a48, result.a48);
+  CHECK_EQ(a49, result.a49);
+  CHECK_EQ(a50, result.a50);
+  CHECK_EQ(a51, result.a51);
+  CHECK_EQ(a52, result.a52);
+  CHECK_EQ(a53, result.a53);
+  CHECK_EQ(a54, result.a54);
+  CHECK_EQ(a55, result.a55);
+  CHECK_EQ(a56, result.a56);
+  CHECK_EQ(a57, result.a57);
+  CHECK_EQ(a58, result.a58);
+  CHECK_EQ(a59, result.a59);
+  CHECK_EQ(a60, result.a60);
+  CHECK_EQ(a61, result.a61);
+  CHECK_EQ(a62, result.a62);
+  CHECK_EQ(a63, result.a63);
+  CHECK_EQ(a64, result.a64);
+  CHECK_EQ(a65, result.a65);
+  CHECK_EQ(a66, result.a66);
+  CHECK_EQ(a67, result.a67);
+  CHECK_EQ(a68, result.a68);
+  CHECK_EQ(a69, result.a69);
+  CHECK_EQ(a70, result.a70);
+  CHECK_EQ(a71, result.a71);
+  CHECK_EQ(a72, result.a72);
+  CHECK_EQ(a73, result.a73);
+  CHECK_EQ(a74, result.a74);
+  CHECK_EQ(a75, result.a75);
+  CHECK_EQ(a76, result.a76);
+  CHECK_EQ(a77, result.a77);
+  CHECK_EQ(a78, result.a78);
+  CHECK_EQ(a79, result.a79);
+  CHECK_EQ(a80, result.a80);
+  CHECK_EQ(a81, result.a81);
+  CHECK_EQ(a82, result.a82);
+  CHECK_EQ(a83, result.a83);
+  CHECK_EQ(a84, result.a84);
+  CHECK_EQ(a85, result.a85);
+  CHECK_EQ(a86, result.a86);
+  CHECK_EQ(a87, result.a87);
+  CHECK_EQ(a88, result.a88);
+  CHECK_EQ(a89, result.a89);
+  CHECK_EQ(a90, result.a90);
+  CHECK_EQ(a91, result.a91);
+  CHECK_EQ(a92, result.a92);
+  CHECK_EQ(a93, result.a93);
+  CHECK_EQ(a94, result.a94);
+  CHECK_EQ(a95, result.a95);
+  CHECK_EQ(a96, result.a96);
+  CHECK_EQ(a97, result.a97);
+  CHECK_EQ(a98, result.a98);
+  CHECK_EQ(a99, result.a99);
+  CHECK_EQ(a100, result.a100);
+  CHECK_EQ(a101, result.a101);
+  CHECK_EQ(a102, result.a102);
+  CHECK_EQ(a103, result.a103);
+  CHECK_EQ(a104, result.a104);
+  CHECK_EQ(a105, result.a105);
+  CHECK_EQ(a106, result.a106);
+  CHECK_EQ(a107, result.a107);
+  CHECK_EQ(a108, result.a108);
+  CHECK_EQ(a109, result.a109);
+  CHECK_EQ(a110, result.a110);
+  CHECK_EQ(a111, result.a111);
+  CHECK_EQ(a112, result.a112);
+  CHECK_EQ(a113, result.a113);
+  CHECK_EQ(a114, result.a114);
+  CHECK_EQ(a115, result.a115);
+  CHECK_EQ(a116, result.a116);
+  CHECK_EQ(a117, result.a117);
+  CHECK_EQ(a118, result.a118);
+  CHECK_EQ(a119, result.a119);
+  CHECK_EQ(a120, result.a120);
+  CHECK_EQ(a121, result.a121);
+  CHECK_EQ(a122, result.a122);
+  CHECK_EQ(a123, result.a123);
+  CHECK_EQ(a124, result.a124);
+  CHECK_EQ(a125, result.a125);
+  CHECK_EQ(a126, result.a126);
+  CHECK_EQ(a127, result.a127);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
+      a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31,
+      a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46,
+      a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61,
+      a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76,
+      a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91,
+      a92, a93, a94, a95, a96, a97, a98, a99, a100, a101, a102, a103, a104,
+      a105, a106, a107, a108, a109, a110, a111, a112, a113, a114, a115, a116,
+      a117, a118, a119, a120, a121, a122, a123, a124, a125, a126, a127);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+  CHECK_EQ(0, result.a5);
+  CHECK_EQ(0, result.a6);
+  CHECK_EQ(0, result.a7);
+  CHECK_EQ(0, result.a8);
+  CHECK_EQ(0, result.a9);
+  CHECK_EQ(0, result.a10);
+  CHECK_EQ(0, result.a11);
+  CHECK_EQ(0, result.a12);
+  CHECK_EQ(0, result.a13);
+  CHECK_EQ(0, result.a14);
+  CHECK_EQ(0, result.a15);
+  CHECK_EQ(0, result.a16);
+  CHECK_EQ(0, result.a17);
+  CHECK_EQ(0, result.a18);
+  CHECK_EQ(0, result.a19);
+  CHECK_EQ(0, result.a20);
+  CHECK_EQ(0, result.a21);
+  CHECK_EQ(0, result.a22);
+  CHECK_EQ(0, result.a23);
+  CHECK_EQ(0, result.a24);
+  CHECK_EQ(0, result.a25);
+  CHECK_EQ(0, result.a26);
+  CHECK_EQ(0, result.a27);
+  CHECK_EQ(0, result.a28);
+  CHECK_EQ(0, result.a29);
+  CHECK_EQ(0, result.a30);
+  CHECK_EQ(0, result.a31);
+  CHECK_EQ(0, result.a32);
+  CHECK_EQ(0, result.a33);
+  CHECK_EQ(0, result.a34);
+  CHECK_EQ(0, result.a35);
+  CHECK_EQ(0, result.a36);
+  CHECK_EQ(0, result.a37);
+  CHECK_EQ(0, result.a38);
+  CHECK_EQ(0, result.a39);
+  CHECK_EQ(0, result.a40);
+  CHECK_EQ(0, result.a41);
+  CHECK_EQ(0, result.a42);
+  CHECK_EQ(0, result.a43);
+  CHECK_EQ(0, result.a44);
+  CHECK_EQ(0, result.a45);
+  CHECK_EQ(0, result.a46);
+  CHECK_EQ(0, result.a47);
+  CHECK_EQ(0, result.a48);
+  CHECK_EQ(0, result.a49);
+  CHECK_EQ(0, result.a50);
+  CHECK_EQ(0, result.a51);
+  CHECK_EQ(0, result.a52);
+  CHECK_EQ(0, result.a53);
+  CHECK_EQ(0, result.a54);
+  CHECK_EQ(0, result.a55);
+  CHECK_EQ(0, result.a56);
+  CHECK_EQ(0, result.a57);
+  CHECK_EQ(0, result.a58);
+  CHECK_EQ(0, result.a59);
+  CHECK_EQ(0, result.a60);
+  CHECK_EQ(0, result.a61);
+  CHECK_EQ(0, result.a62);
+  CHECK_EQ(0, result.a63);
+  CHECK_EQ(0, result.a64);
+  CHECK_EQ(0, result.a65);
+  CHECK_EQ(0, result.a66);
+  CHECK_EQ(0, result.a67);
+  CHECK_EQ(0, result.a68);
+  CHECK_EQ(0, result.a69);
+  CHECK_EQ(0, result.a70);
+  CHECK_EQ(0, result.a71);
+  CHECK_EQ(0, result.a72);
+  CHECK_EQ(0, result.a73);
+  CHECK_EQ(0, result.a74);
+  CHECK_EQ(0, result.a75);
+  CHECK_EQ(0, result.a76);
+  CHECK_EQ(0, result.a77);
+  CHECK_EQ(0, result.a78);
+  CHECK_EQ(0, result.a79);
+  CHECK_EQ(0, result.a80);
+  CHECK_EQ(0, result.a81);
+  CHECK_EQ(0, result.a82);
+  CHECK_EQ(0, result.a83);
+  CHECK_EQ(0, result.a84);
+  CHECK_EQ(0, result.a85);
+  CHECK_EQ(0, result.a86);
+  CHECK_EQ(0, result.a87);
+  CHECK_EQ(0, result.a88);
+  CHECK_EQ(0, result.a89);
+  CHECK_EQ(0, result.a90);
+  CHECK_EQ(0, result.a91);
+  CHECK_EQ(0, result.a92);
+  CHECK_EQ(0, result.a93);
+  CHECK_EQ(0, result.a94);
+  CHECK_EQ(0, result.a95);
+  CHECK_EQ(0, result.a96);
+  CHECK_EQ(0, result.a97);
+  CHECK_EQ(0, result.a98);
+  CHECK_EQ(0, result.a99);
+  CHECK_EQ(0, result.a100);
+  CHECK_EQ(0, result.a101);
+  CHECK_EQ(0, result.a102);
+  CHECK_EQ(0, result.a103);
+  CHECK_EQ(0, result.a104);
+  CHECK_EQ(0, result.a105);
+  CHECK_EQ(0, result.a106);
+  CHECK_EQ(0, result.a107);
+  CHECK_EQ(0, result.a108);
+  CHECK_EQ(0, result.a109);
+  CHECK_EQ(0, result.a110);
+  CHECK_EQ(0, result.a111);
+  CHECK_EQ(0, result.a112);
+  CHECK_EQ(0, result.a113);
+  CHECK_EQ(0, result.a114);
+  CHECK_EQ(0, result.a115);
+  CHECK_EQ(0, result.a116);
+  CHECK_EQ(0, result.a117);
+  CHECK_EQ(0, result.a118);
+  CHECK_EQ(0, result.a119);
+  CHECK_EQ(0, result.a120);
+  CHECK_EQ(0, result.a121);
+  CHECK_EQ(0, result.a122);
+  CHECK_EQ(0, result.a123);
+  CHECK_EQ(0, result.a124);
+  CHECK_EQ(0, result.a125);
+  CHECK_EQ(0, result.a126);
+  CHECK_EQ(0, result.a127);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16,
+      a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31,
+      a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46,
+      a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61,
+      a62, a63, a64, a65, a66, a67, a68, a69, a70, a71, a72, a73, a74, a75, a76,
+      a77, a78, a79, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a90, a91,
+      a92, a93, a94, a95, a96, a97, a98, a99, a100, a101, a102, a103, a104,
+      a105, a106, a107, a108, a109, a110, a111, a112, a113, a114, a115, a116,
+      a117, a118, a119, a120, a121, a122, a123, a124, a125, a126, a127);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+  CHECK_EQ(0, result.a5);
+  CHECK_EQ(0, result.a6);
+  CHECK_EQ(0, result.a7);
+  CHECK_EQ(0, result.a8);
+  CHECK_EQ(0, result.a9);
+  CHECK_EQ(0, result.a10);
+  CHECK_EQ(0, result.a11);
+  CHECK_EQ(0, result.a12);
+  CHECK_EQ(0, result.a13);
+  CHECK_EQ(0, result.a14);
+  CHECK_EQ(0, result.a15);
+  CHECK_EQ(0, result.a16);
+  CHECK_EQ(0, result.a17);
+  CHECK_EQ(0, result.a18);
+  CHECK_EQ(0, result.a19);
+  CHECK_EQ(0, result.a20);
+  CHECK_EQ(0, result.a21);
+  CHECK_EQ(0, result.a22);
+  CHECK_EQ(0, result.a23);
+  CHECK_EQ(0, result.a24);
+  CHECK_EQ(0, result.a25);
+  CHECK_EQ(0, result.a26);
+  CHECK_EQ(0, result.a27);
+  CHECK_EQ(0, result.a28);
+  CHECK_EQ(0, result.a29);
+  CHECK_EQ(0, result.a30);
+  CHECK_EQ(0, result.a31);
+  CHECK_EQ(0, result.a32);
+  CHECK_EQ(0, result.a33);
+  CHECK_EQ(0, result.a34);
+  CHECK_EQ(0, result.a35);
+  CHECK_EQ(0, result.a36);
+  CHECK_EQ(0, result.a37);
+  CHECK_EQ(0, result.a38);
+  CHECK_EQ(0, result.a39);
+  CHECK_EQ(0, result.a40);
+  CHECK_EQ(0, result.a41);
+  CHECK_EQ(0, result.a42);
+  CHECK_EQ(0, result.a43);
+  CHECK_EQ(0, result.a44);
+  CHECK_EQ(0, result.a45);
+  CHECK_EQ(0, result.a46);
+  CHECK_EQ(0, result.a47);
+  CHECK_EQ(0, result.a48);
+  CHECK_EQ(0, result.a49);
+  CHECK_EQ(0, result.a50);
+  CHECK_EQ(0, result.a51);
+  CHECK_EQ(0, result.a52);
+  CHECK_EQ(0, result.a53);
+  CHECK_EQ(0, result.a54);
+  CHECK_EQ(0, result.a55);
+  CHECK_EQ(0, result.a56);
+  CHECK_EQ(0, result.a57);
+  CHECK_EQ(0, result.a58);
+  CHECK_EQ(0, result.a59);
+  CHECK_EQ(0, result.a60);
+  CHECK_EQ(0, result.a61);
+  CHECK_EQ(0, result.a62);
+  CHECK_EQ(0, result.a63);
+  CHECK_EQ(0, result.a64);
+  CHECK_EQ(0, result.a65);
+  CHECK_EQ(0, result.a66);
+  CHECK_EQ(0, result.a67);
+  CHECK_EQ(0, result.a68);
+  CHECK_EQ(0, result.a69);
+  CHECK_EQ(0, result.a70);
+  CHECK_EQ(0, result.a71);
+  CHECK_EQ(0, result.a72);
+  CHECK_EQ(0, result.a73);
+  CHECK_EQ(0, result.a74);
+  CHECK_EQ(0, result.a75);
+  CHECK_EQ(0, result.a76);
+  CHECK_EQ(0, result.a77);
+  CHECK_EQ(0, result.a78);
+  CHECK_EQ(0, result.a79);
+  CHECK_EQ(0, result.a80);
+  CHECK_EQ(0, result.a81);
+  CHECK_EQ(0, result.a82);
+  CHECK_EQ(0, result.a83);
+  CHECK_EQ(0, result.a84);
+  CHECK_EQ(0, result.a85);
+  CHECK_EQ(0, result.a86);
+  CHECK_EQ(0, result.a87);
+  CHECK_EQ(0, result.a88);
+  CHECK_EQ(0, result.a89);
+  CHECK_EQ(0, result.a90);
+  CHECK_EQ(0, result.a91);
+  CHECK_EQ(0, result.a92);
+  CHECK_EQ(0, result.a93);
+  CHECK_EQ(0, result.a94);
+  CHECK_EQ(0, result.a95);
+  CHECK_EQ(0, result.a96);
+  CHECK_EQ(0, result.a97);
+  CHECK_EQ(0, result.a98);
+  CHECK_EQ(0, result.a99);
+  CHECK_EQ(0, result.a100);
+  CHECK_EQ(0, result.a101);
+  CHECK_EQ(0, result.a102);
+  CHECK_EQ(0, result.a103);
+  CHECK_EQ(0, result.a104);
+  CHECK_EQ(0, result.a105);
+  CHECK_EQ(0, result.a106);
+  CHECK_EQ(0, result.a107);
+  CHECK_EQ(0, result.a108);
+  CHECK_EQ(0, result.a109);
+  CHECK_EQ(0, result.a110);
+  CHECK_EQ(0, result.a111);
+  CHECK_EQ(0, result.a112);
+  CHECK_EQ(0, result.a113);
+  CHECK_EQ(0, result.a114);
+  CHECK_EQ(0, result.a115);
+  CHECK_EQ(0, result.a116);
+  CHECK_EQ(0, result.a117);
+  CHECK_EQ(0, result.a118);
+  CHECK_EQ(0, result.a119);
+  CHECK_EQ(0, result.a120);
+  CHECK_EQ(0, result.a121);
+  CHECK_EQ(0, result.a122);
+  CHECK_EQ(0, result.a123);
+  CHECK_EQ(0, result.a124);
+  CHECK_EQ(0, result.a125);
+  CHECK_EQ(0, result.a126);
+  CHECK_EQ(0, result.a127);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test that a struct passed in as argument can be returned.
+// Especially for ffi callbacks.
+// Struct is passed in int registers in most ABIs.
+DART_EXPORT intptr_t TestReturnStructArgumentStruct1ByteInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct1ByteInt (*f)(Struct1ByteInt a0)) {
+  Struct1ByteInt a0;
+
+  a0.a0 = -1;
+
+  std::cout << "Calling TestReturnStructArgumentStruct1ByteInt("
+            << "((" << static_cast<int>(a0.a0) << "))"
+            << ")\n";
+
+  Struct1ByteInt result = f(a0);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ")"
+            << "\n";
+
+  CHECK_EQ(a0.a0, result.a0);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result.a0);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result.a0);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test that a struct passed in as argument can be returned.
+// Especially for ffi callbacks.
+// Struct is passed on stack on all ABIs.
+DART_EXPORT intptr_t TestReturnStructArgumentInt32x8Struct1ByteInt(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct1ByteInt (*f)(int32_t a0,
+                        int32_t a1,
+                        int32_t a2,
+                        int32_t a3,
+                        int32_t a4,
+                        int32_t a5,
+                        int32_t a6,
+                        int32_t a7,
+                        Struct1ByteInt a8)) {
+  int32_t a0;
+  int32_t a1;
+  int32_t a2;
+  int32_t a3;
+  int32_t a4;
+  int32_t a5;
+  int32_t a6;
+  int32_t a7;
+  Struct1ByteInt a8;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+  a5 = 6;
+  a6 = -7;
+  a7 = 8;
+  a8.a0 = -9;
+
+  std::cout << "Calling TestReturnStructArgumentInt32x8Struct1ByteInt("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", " << a6 << ", " << a7 << ", ("
+            << static_cast<int>(a8.a0) << "))"
+            << ")\n";
+
+  Struct1ByteInt result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ")"
+            << "\n";
+
+  CHECK_EQ(a8.a0, result.a0);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_EQ(0, result.a0);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_EQ(0, result.a0);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test that a struct passed in as argument can be returned.
+// Especially for ffi callbacks.
+// Struct is passed in float registers in most ABIs.
+DART_EXPORT intptr_t TestReturnStructArgumentStruct8BytesHomogeneousFloat(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct8BytesHomogeneousFloat (*f)(Struct8BytesHomogeneousFloat a0)) {
+  Struct8BytesHomogeneousFloat a0;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+
+  std::cout << "Calling TestReturnStructArgumentStruct8BytesHomogeneousFloat("
+            << "((" << a0.a0 << ", " << a0.a1 << "))"
+            << ")\n";
+
+  Struct8BytesHomogeneousFloat result = f(a0);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ")"
+            << "\n";
+
+  CHECK_APPROX(a0.a0, result.a0);
+  CHECK_APPROX(a0.a1, result.a1);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_APPROX(0.0, result.a0);
+  CHECK_APPROX(0.0, result.a1);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On arm64, both argument and return value are passed in by pointer.
+DART_EXPORT intptr_t TestReturnStructArgumentStruct20BytesHomogeneousInt32(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct20BytesHomogeneousInt32 (*f)(Struct20BytesHomogeneousInt32 a0)) {
+  Struct20BytesHomogeneousInt32 a0;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a0.a3 = 4;
+  a0.a4 = -5;
+
+  std::cout << "Calling TestReturnStructArgumentStruct20BytesHomogeneousInt32("
+            << "((" << a0.a0 << ", " << a0.a1 << ", " << a0.a2 << ", " << a0.a3
+            << ", " << a0.a4 << "))"
+            << ")\n";
+
+  Struct20BytesHomogeneousInt32 result = f(a0);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  CHECK_EQ(a0.a0, result.a0);
+  CHECK_EQ(a0.a1, result.a1);
+  CHECK_EQ(a0.a2, result.a2);
+  CHECK_EQ(a0.a3, result.a3);
+  CHECK_EQ(a0.a4, result.a4);
+
+  // Pass argument that will make the Dart callback throw.
+  a0.a0 = 42;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  // Pass argument that will make the Dart callback return null.
+  a0.a0 = 84;
+
+  result = f(a0);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// On arm64, both argument and return value are passed in by pointer.
+// Ints exhaust registers, so that pointer is passed on stack.
+DART_EXPORT intptr_t TestReturnStructArgumentInt32x8Struct20BytesHomogeneou(
+    // NOLINTNEXTLINE(whitespace/parens)
+    Struct20BytesHomogeneousInt32 (*f)(int32_t a0,
+                                       int32_t a1,
+                                       int32_t a2,
+                                       int32_t a3,
+                                       int32_t a4,
+                                       int32_t a5,
+                                       int32_t a6,
+                                       int32_t a7,
+                                       Struct20BytesHomogeneousInt32 a8)) {
+  int32_t a0;
+  int32_t a1;
+  int32_t a2;
+  int32_t a3;
+  int32_t a4;
+  int32_t a5;
+  int32_t a6;
+  int32_t a7;
+  Struct20BytesHomogeneousInt32 a8;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+  a5 = 6;
+  a6 = -7;
+  a7 = 8;
+  a8.a0 = -9;
+  a8.a1 = 10;
+  a8.a2 = -11;
+  a8.a3 = 12;
+  a8.a4 = -13;
+
+  std::cout << "Calling TestReturnStructArgumentInt32x8Struct20BytesHomogeneou("
+            << "(" << a0 << ", " << a1 << ", " << a2 << ", " << a3 << ", " << a4
+            << ", " << a5 << ", " << a6 << ", " << a7 << ", (" << a8.a0 << ", "
+            << a8.a1 << ", " << a8.a2 << ", " << a8.a3 << ", " << a8.a4 << "))"
+            << ")\n";
+
+  Struct20BytesHomogeneousInt32 result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  std::cout << "result = "
+            << "(" << result.a0 << ", " << result.a1 << ", " << result.a2
+            << ", " << result.a3 << ", " << result.a4 << ")"
+            << "\n";
+
+  CHECK_EQ(a8.a0, result.a0);
+  CHECK_EQ(a8.a1, result.a1);
+  CHECK_EQ(a8.a2, result.a2);
+  CHECK_EQ(a8.a3, result.a3);
+  CHECK_EQ(a8.a4, result.a4);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+  CHECK_EQ(0, result.a3);
+  CHECK_EQ(0, result.a4);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 16 byte int within struct.
+DART_EXPORT intptr_t TestReturnStructAlignmentInt16(
+    // NOLINTNEXTLINE(whitespace/parens)
+    StructAlignmentInt16 (*f)(int8_t a0, int16_t a1, int8_t a2)) {
+  int8_t a0;
+  int16_t a1;
+  int8_t a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStructAlignmentInt16("
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ")"
+            << ")\n";
+
+  StructAlignmentInt16 result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 32 byte int within struct.
+DART_EXPORT intptr_t TestReturnStructAlignmentInt32(
+    // NOLINTNEXTLINE(whitespace/parens)
+    StructAlignmentInt32 (*f)(int8_t a0, int32_t a1, int8_t a2)) {
+  int8_t a0;
+  int32_t a1;
+  int8_t a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStructAlignmentInt32("
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ")"
+            << ")\n";
+
+  StructAlignmentInt32 result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+// Used for testing structs by value.
+// Test alignment and padding of 64 byte int within struct.
+DART_EXPORT intptr_t TestReturnStructAlignmentInt64(
+    // NOLINTNEXTLINE(whitespace/parens)
+    StructAlignmentInt64 (*f)(int8_t a0, int64_t a1, int8_t a2)) {
+  int8_t a0;
+  int64_t a1;
+  int8_t a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  std::cout << "Calling TestReturnStructAlignmentInt64("
+            << "(" << static_cast<int>(a0) << ", " << a1 << ", "
+            << static_cast<int>(a2) << ")"
+            << ")\n";
+
+  StructAlignmentInt64 result = f(a0, a1, a2);
+
+  std::cout << "result = "
+            << "(" << static_cast<int>(result.a0) << ", " << result.a1 << ", "
+            << static_cast<int>(result.a2) << ")"
+            << "\n";
+
+  CHECK_EQ(a0, result.a0);
+  CHECK_EQ(a1, result.a1);
+  CHECK_EQ(a2, result.a2);
+
+  // Pass argument that will make the Dart callback throw.
+  a0 = 42;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  // Pass argument that will make the Dart callback return null.
+  a0 = 84;
+
+  result = f(a0, a1, a2);
+
+  CHECK_EQ(0, result.a0);
+  CHECK_EQ(0, result.a1);
+  CHECK_EQ(0, result.a2);
+
+  return 0;
+}
+
+}  // namespace dart
diff --git a/tests/ffi/callback_tests_utils.dart b/tests/ffi/callback_tests_utils.dart
index ac5fdcb..e34a52b 100644
--- a/tests/ffi/callback_tests_utils.dart
+++ b/tests/ffi/callback_tests_utils.dart
@@ -16,19 +16,23 @@
 class CallbackTest {
   final String name;
   final Pointer callback;
-  final bool skip;
+  final void Function() afterCallbackChecks;
 
-  CallbackTest(this.name, this.callback, {bool skipIf: false})
-      : skip = skipIf {}
+  CallbackTest(this.name, this.callback) : afterCallbackChecks = noChecks {}
+  CallbackTest.withCheck(this.name, this.callback, this.afterCallbackChecks) {}
 
   void run() {
-    if (skip) return;
-
     final NativeCallbackTestFn tester = ffiTestFunctions
         .lookupFunction<NativeCallbackTest, NativeCallbackTestFn>("Test$name");
+
     final int testCode = tester(callback);
+
     if (testCode != 0) {
       Expect.fail("Test $name failed.");
     }
+
+    afterCallbackChecks();
   }
 }
+
+void noChecks() {}
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 37ab3e9..3baf069 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -2,6 +2,11 @@
 # 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.
 
+# TODO(dartbug.com/36730): Implement structs by value.
+function_callbacks_structs_by_value_generated_test: Skip
+function_callbacks_structs_by_value_test: Skip
+function_structs_by_value_generated_test: Skip
+
 [ $builder_tag == msan ]
 vmspecific_handle_test: Skip # https://dartbug.com/42314
 
diff --git a/tests/ffi/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
new file mode 100644
index 0000000..8499285
--- /dev/null
+++ b/tests/ffi/function_callbacks_structs_by_value_generated_test.dart
@@ -0,0 +1,5896 @@
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'callback_tests_utils.dart';
+
+// Reuse the struct classes.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  testCases.forEach((t) {
+    print("==== Running " + t.name);
+    t.run();
+  });
+}
+
+final testCases = [
+  CallbackTest.withCheck(
+      "PassStruct1ByteIntx10",
+      Pointer.fromFunction<PassStruct1ByteIntx10Type>(passStruct1ByteIntx10, 0),
+      passStruct1ByteIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct3BytesIntx10",
+      Pointer.fromFunction<PassStruct3BytesIntx10Type>(
+          passStruct3BytesIntx10, 0),
+      passStruct3BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct4BytesHomogeneousInt16x10",
+      Pointer.fromFunction<PassStruct4BytesHomogeneousInt16x10Type>(
+          passStruct4BytesHomogeneousInt16x10, 0),
+      passStruct4BytesHomogeneousInt16x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct7BytesIntx10",
+      Pointer.fromFunction<PassStruct7BytesIntx10Type>(
+          passStruct7BytesIntx10, 0),
+      passStruct7BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesIntx10",
+      Pointer.fromFunction<PassStruct8BytesIntx10Type>(
+          passStruct8BytesIntx10, 0),
+      passStruct8BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesHomogeneousFloatx10",
+      Pointer.fromFunction<PassStruct8BytesHomogeneousFloatx10Type>(
+          passStruct8BytesHomogeneousFloatx10, 0.0),
+      passStruct8BytesHomogeneousFloatx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesMixedx10",
+      Pointer.fromFunction<PassStruct8BytesMixedx10Type>(
+          passStruct8BytesMixedx10, 0.0),
+      passStruct8BytesMixedx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct9BytesIntx10",
+      Pointer.fromFunction<PassStruct9BytesIntx10Type>(
+          passStruct9BytesIntx10, 0),
+      passStruct9BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct9BytesHomogeneousUint82x10",
+      Pointer.fromFunction<PassStruct9BytesHomogeneousUint82x10Type>(
+          passStruct9BytesHomogeneousUint82x10, 0),
+      passStruct9BytesHomogeneousUint82x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct12BytesHomogeneousFloatx6",
+      Pointer.fromFunction<PassStruct12BytesHomogeneousFloatx6Type>(
+          passStruct12BytesHomogeneousFloatx6, 0.0),
+      passStruct12BytesHomogeneousFloatx6AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct16BytesHomogeneousFloatx5",
+      Pointer.fromFunction<PassStruct16BytesHomogeneousFloatx5Type>(
+          passStruct16BytesHomogeneousFloatx5, 0.0),
+      passStruct16BytesHomogeneousFloatx5AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct16BytesMixedx10",
+      Pointer.fromFunction<PassStruct16BytesMixedx10Type>(
+          passStruct16BytesMixedx10, 0.0),
+      passStruct16BytesMixedx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct16BytesMixed2x10",
+      Pointer.fromFunction<PassStruct16BytesMixed2x10Type>(
+          passStruct16BytesMixed2x10, 0.0),
+      passStruct16BytesMixed2x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct17BytesIntx10",
+      Pointer.fromFunction<PassStruct17BytesIntx10Type>(
+          passStruct17BytesIntx10, 0),
+      passStruct17BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct19BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct19BytesHomogeneousUint8x10Type>(
+          passStruct19BytesHomogeneousUint8x10, 0),
+      passStruct19BytesHomogeneousUint8x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct20BytesHomogeneousInt32x10",
+      Pointer.fromFunction<PassStruct20BytesHomogeneousInt32x10Type>(
+          passStruct20BytesHomogeneousInt32x10, 0),
+      passStruct20BytesHomogeneousInt32x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct20BytesHomogeneousFloat",
+      Pointer.fromFunction<PassStruct20BytesHomogeneousFloatType>(
+          passStruct20BytesHomogeneousFloat, 0.0),
+      passStruct20BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct32BytesHomogeneousDoublex5",
+      Pointer.fromFunction<PassStruct32BytesHomogeneousDoublex5Type>(
+          passStruct32BytesHomogeneousDoublex5, 0.0),
+      passStruct32BytesHomogeneousDoublex5AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct40BytesHomogeneousDouble",
+      Pointer.fromFunction<PassStruct40BytesHomogeneousDoubleType>(
+          passStruct40BytesHomogeneousDouble, 0.0),
+      passStruct40BytesHomogeneousDoubleAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct1024BytesHomogeneousUint64",
+      Pointer.fromFunction<PassStruct1024BytesHomogeneousUint64Type>(
+          passStruct1024BytesHomogeneousUint64, 0),
+      passStruct1024BytesHomogeneousUint64AfterCallback),
+  CallbackTest.withCheck(
+      "PassFloatStruct16BytesHomogeneousFloatFloatStruct1",
+      Pointer.fromFunction<
+              PassFloatStruct16BytesHomogeneousFloatFloatStruct1Type>(
+          passFloatStruct16BytesHomogeneousFloatFloatStruct1, 0.0),
+      passFloatStruct16BytesHomogeneousFloatFloatStruct1AfterCallback),
+  CallbackTest.withCheck(
+      "PassFloatStruct32BytesHomogeneousDoubleFloatStruct",
+      Pointer.fromFunction<
+              PassFloatStruct32BytesHomogeneousDoubleFloatStructType>(
+          passFloatStruct32BytesHomogeneousDoubleFloatStruct, 0.0),
+      passFloatStruct32BytesHomogeneousDoubleFloatStructAfterCallback),
+  CallbackTest.withCheck(
+      "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn",
+      Pointer.fromFunction<
+              PassInt8Struct16BytesMixedInt8Struct16BytesMixedInType>(
+          passInt8Struct16BytesMixedInt8Struct16BytesMixedIn, 0.0),
+      passInt8Struct16BytesMixedInt8Struct16BytesMixedInAfterCallback),
+  CallbackTest.withCheck(
+      "PassDoublex6Struct16BytesMixedx4Int32",
+      Pointer.fromFunction<PassDoublex6Struct16BytesMixedx4Int32Type>(
+          passDoublex6Struct16BytesMixedx4Int32, 0.0),
+      passDoublex6Struct16BytesMixedx4Int32AfterCallback),
+  CallbackTest.withCheck(
+      "PassInt32x4Struct16BytesMixedx4Double",
+      Pointer.fromFunction<PassInt32x4Struct16BytesMixedx4DoubleType>(
+          passInt32x4Struct16BytesMixedx4Double, 0.0),
+      passInt32x4Struct16BytesMixedx4DoubleAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo",
+      Pointer.fromFunction<
+              PassStruct40BytesHomogeneousDoubleStruct4BytesHomoType>(
+          passStruct40BytesHomogeneousDoubleStruct4BytesHomo, 0.0),
+      passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback),
+  CallbackTest.withCheck(
+      "PassStructAlignmentInt16",
+      Pointer.fromFunction<PassStructAlignmentInt16Type>(
+          passStructAlignmentInt16, 0),
+      passStructAlignmentInt16AfterCallback),
+  CallbackTest.withCheck(
+      "PassStructAlignmentInt32",
+      Pointer.fromFunction<PassStructAlignmentInt32Type>(
+          passStructAlignmentInt32, 0),
+      passStructAlignmentInt32AfterCallback),
+  CallbackTest.withCheck(
+      "PassStructAlignmentInt64",
+      Pointer.fromFunction<PassStructAlignmentInt64Type>(
+          passStructAlignmentInt64, 0),
+      passStructAlignmentInt64AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct1ByteInt",
+      Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
+      returnStruct1ByteIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct3BytesInt",
+      Pointer.fromFunction<ReturnStruct3BytesIntType>(returnStruct3BytesInt),
+      returnStruct3BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct4BytesHomogeneousInt16",
+      Pointer.fromFunction<ReturnStruct4BytesHomogeneousInt16Type>(
+          returnStruct4BytesHomogeneousInt16),
+      returnStruct4BytesHomogeneousInt16AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct7BytesInt",
+      Pointer.fromFunction<ReturnStruct7BytesIntType>(returnStruct7BytesInt),
+      returnStruct7BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesInt",
+      Pointer.fromFunction<ReturnStruct8BytesIntType>(returnStruct8BytesInt),
+      returnStruct8BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct8BytesHomogeneousFloatType>(
+          returnStruct8BytesHomogeneousFloat),
+      returnStruct8BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesMixed",
+      Pointer.fromFunction<ReturnStruct8BytesMixedType>(
+          returnStruct8BytesMixed),
+      returnStruct8BytesMixedAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct9BytesInt",
+      Pointer.fromFunction<ReturnStruct9BytesIntType>(returnStruct9BytesInt),
+      returnStruct9BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct9BytesHomogeneousUint82",
+      Pointer.fromFunction<ReturnStruct9BytesHomogeneousUint82Type>(
+          returnStruct9BytesHomogeneousUint82),
+      returnStruct9BytesHomogeneousUint82AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct12BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct12BytesHomogeneousFloatType>(
+          returnStruct12BytesHomogeneousFloat),
+      returnStruct12BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct16BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct16BytesHomogeneousFloatType>(
+          returnStruct16BytesHomogeneousFloat),
+      returnStruct16BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct16BytesMixed",
+      Pointer.fromFunction<ReturnStruct16BytesMixedType>(
+          returnStruct16BytesMixed),
+      returnStruct16BytesMixedAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct16BytesMixed2",
+      Pointer.fromFunction<ReturnStruct16BytesMixed2Type>(
+          returnStruct16BytesMixed2),
+      returnStruct16BytesMixed2AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct17BytesInt",
+      Pointer.fromFunction<ReturnStruct17BytesIntType>(returnStruct17BytesInt),
+      returnStruct17BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct19BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct19BytesHomogeneousUint8Type>(
+          returnStruct19BytesHomogeneousUint8),
+      returnStruct19BytesHomogeneousUint8AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct20BytesHomogeneousInt32",
+      Pointer.fromFunction<ReturnStruct20BytesHomogeneousInt32Type>(
+          returnStruct20BytesHomogeneousInt32),
+      returnStruct20BytesHomogeneousInt32AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct20BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct20BytesHomogeneousFloatType>(
+          returnStruct20BytesHomogeneousFloat),
+      returnStruct20BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct32BytesHomogeneousDouble",
+      Pointer.fromFunction<ReturnStruct32BytesHomogeneousDoubleType>(
+          returnStruct32BytesHomogeneousDouble),
+      returnStruct32BytesHomogeneousDoubleAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct40BytesHomogeneousDouble",
+      Pointer.fromFunction<ReturnStruct40BytesHomogeneousDoubleType>(
+          returnStruct40BytesHomogeneousDouble),
+      returnStruct40BytesHomogeneousDoubleAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct1024BytesHomogeneousUint64",
+      Pointer.fromFunction<ReturnStruct1024BytesHomogeneousUint64Type>(
+          returnStruct1024BytesHomogeneousUint64),
+      returnStruct1024BytesHomogeneousUint64AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentStruct1ByteInt",
+      Pointer.fromFunction<ReturnStructArgumentStruct1ByteIntType>(
+          returnStructArgumentStruct1ByteInt),
+      returnStructArgumentStruct1ByteIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentInt32x8Struct1ByteInt",
+      Pointer.fromFunction<ReturnStructArgumentInt32x8Struct1ByteIntType>(
+          returnStructArgumentInt32x8Struct1ByteInt),
+      returnStructArgumentInt32x8Struct1ByteIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentStruct8BytesHomogeneousFloat",
+      Pointer.fromFunction<
+              ReturnStructArgumentStruct8BytesHomogeneousFloatType>(
+          returnStructArgumentStruct8BytesHomogeneousFloat),
+      returnStructArgumentStruct8BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentStruct20BytesHomogeneousInt32",
+      Pointer.fromFunction<
+              ReturnStructArgumentStruct20BytesHomogeneousInt32Type>(
+          returnStructArgumentStruct20BytesHomogeneousInt32),
+      returnStructArgumentStruct20BytesHomogeneousInt32AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentInt32x8Struct20BytesHomogeneou",
+      Pointer.fromFunction<
+              ReturnStructArgumentInt32x8Struct20BytesHomogeneouType>(
+          returnStructArgumentInt32x8Struct20BytesHomogeneou),
+      returnStructArgumentInt32x8Struct20BytesHomogeneouAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructAlignmentInt16",
+      Pointer.fromFunction<ReturnStructAlignmentInt16Type>(
+          returnStructAlignmentInt16),
+      returnStructAlignmentInt16AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructAlignmentInt32",
+      Pointer.fromFunction<ReturnStructAlignmentInt32Type>(
+          returnStructAlignmentInt32),
+      returnStructAlignmentInt32AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructAlignmentInt64",
+      Pointer.fromFunction<ReturnStructAlignmentInt64Type>(
+          returnStructAlignmentInt64),
+      returnStructAlignmentInt64AfterCallback),
+];
+typedef PassStruct1ByteIntx10Type = Int64 Function(
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct1ByteInt passStruct1ByteIntx10_a0 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a1 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a2 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a3 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a4 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a5 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a6 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a7 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a8 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a9 = Struct1ByteInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct1ByteIntx10Result = 0;
+
+int passStruct1ByteIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct1ByteIntx10_a0.a0;
+  result += passStruct1ByteIntx10_a1.a0;
+  result += passStruct1ByteIntx10_a2.a0;
+  result += passStruct1ByteIntx10_a3.a0;
+  result += passStruct1ByteIntx10_a4.a0;
+  result += passStruct1ByteIntx10_a5.a0;
+  result += passStruct1ByteIntx10_a6.a0;
+  result += passStruct1ByteIntx10_a7.a0;
+  result += passStruct1ByteIntx10_a8.a0;
+  result += passStruct1ByteIntx10_a9.a0;
+
+  passStruct1ByteIntx10Result = result;
+
+  return result;
+}
+
+/// Smallest struct with data.
+/// 10 struct arguments will exhaust available registers.
+int passStruct1ByteIntx10(
+    Struct1ByteInt a0,
+    Struct1ByteInt a1,
+    Struct1ByteInt a2,
+    Struct1ByteInt a3,
+    Struct1ByteInt a4,
+    Struct1ByteInt a5,
+    Struct1ByteInt a6,
+    Struct1ByteInt a7,
+    Struct1ByteInt a8,
+    Struct1ByteInt a9) {
+  print(
+      "passStruct1ByteIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct1ByteIntx10 throwing on purpuse!");
+  }
+
+  passStruct1ByteIntx10_a0 = a0;
+  passStruct1ByteIntx10_a1 = a1;
+  passStruct1ByteIntx10_a2 = a2;
+  passStruct1ByteIntx10_a3 = a3;
+  passStruct1ByteIntx10_a4 = a4;
+  passStruct1ByteIntx10_a5 = a5;
+  passStruct1ByteIntx10_a6 = a6;
+  passStruct1ByteIntx10_a7 = a7;
+  passStruct1ByteIntx10_a8 = a8;
+  passStruct1ByteIntx10_a9 = a9;
+
+  final result = passStruct1ByteIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct1ByteIntx10AfterCallback() {
+  final result = passStruct1ByteIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(5, result);
+}
+
+typedef PassStruct3BytesIntx10Type = Int64 Function(
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct3BytesInt passStruct3BytesIntx10_a0 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a1 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a2 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a3 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a4 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a5 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a6 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a7 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a8 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a9 = Struct3BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct3BytesIntx10Result = 0;
+
+int passStruct3BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct3BytesIntx10_a0.a0;
+  result += passStruct3BytesIntx10_a0.a1;
+  result += passStruct3BytesIntx10_a1.a0;
+  result += passStruct3BytesIntx10_a1.a1;
+  result += passStruct3BytesIntx10_a2.a0;
+  result += passStruct3BytesIntx10_a2.a1;
+  result += passStruct3BytesIntx10_a3.a0;
+  result += passStruct3BytesIntx10_a3.a1;
+  result += passStruct3BytesIntx10_a4.a0;
+  result += passStruct3BytesIntx10_a4.a1;
+  result += passStruct3BytesIntx10_a5.a0;
+  result += passStruct3BytesIntx10_a5.a1;
+  result += passStruct3BytesIntx10_a6.a0;
+  result += passStruct3BytesIntx10_a6.a1;
+  result += passStruct3BytesIntx10_a7.a0;
+  result += passStruct3BytesIntx10_a7.a1;
+  result += passStruct3BytesIntx10_a8.a0;
+  result += passStruct3BytesIntx10_a8.a1;
+  result += passStruct3BytesIntx10_a9.a0;
+  result += passStruct3BytesIntx10_a9.a1;
+
+  passStruct3BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Not a multiple of word size, not a power of two.
+/// 10 struct arguments will exhaust available registers.
+int passStruct3BytesIntx10(
+    Struct3BytesInt a0,
+    Struct3BytesInt a1,
+    Struct3BytesInt a2,
+    Struct3BytesInt a3,
+    Struct3BytesInt a4,
+    Struct3BytesInt a5,
+    Struct3BytesInt a6,
+    Struct3BytesInt a7,
+    Struct3BytesInt a8,
+    Struct3BytesInt a9) {
+  print(
+      "passStruct3BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct3BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct3BytesIntx10_a0 = a0;
+  passStruct3BytesIntx10_a1 = a1;
+  passStruct3BytesIntx10_a2 = a2;
+  passStruct3BytesIntx10_a3 = a3;
+  passStruct3BytesIntx10_a4 = a4;
+  passStruct3BytesIntx10_a5 = a5;
+  passStruct3BytesIntx10_a6 = a6;
+  passStruct3BytesIntx10_a7 = a7;
+  passStruct3BytesIntx10_a8 = a8;
+  passStruct3BytesIntx10_a9 = a9;
+
+  final result = passStruct3BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct3BytesIntx10AfterCallback() {
+  final result = passStruct3BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct4BytesHomogeneousInt16x10Type = Int64 Function(
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16);
+
+// Global variables to be able to test inputs after callback returned.
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a0 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a1 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a2 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a3 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a4 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a5 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a6 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a7 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a8 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a9 =
+    Struct4BytesHomogeneousInt16();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct4BytesHomogeneousInt16x10Result = 0;
+
+int passStruct4BytesHomogeneousInt16x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct4BytesHomogeneousInt16x10_a0.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a0.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a1.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a1.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a2.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a2.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a3.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a3.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a4.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a4.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a5.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a5.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a6.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a6.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a7.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a7.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a8.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a8.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a9.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a9.a1;
+
+  passStruct4BytesHomogeneousInt16x10Result = result;
+
+  return result;
+}
+
+/// Exactly word size on 32-bit architectures.
+/// 10 struct arguments will exhaust available registers.
+int passStruct4BytesHomogeneousInt16x10(
+    Struct4BytesHomogeneousInt16 a0,
+    Struct4BytesHomogeneousInt16 a1,
+    Struct4BytesHomogeneousInt16 a2,
+    Struct4BytesHomogeneousInt16 a3,
+    Struct4BytesHomogeneousInt16 a4,
+    Struct4BytesHomogeneousInt16 a5,
+    Struct4BytesHomogeneousInt16 a6,
+    Struct4BytesHomogeneousInt16 a7,
+    Struct4BytesHomogeneousInt16 a8,
+    Struct4BytesHomogeneousInt16 a9) {
+  print(
+      "passStruct4BytesHomogeneousInt16x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct4BytesHomogeneousInt16x10 throwing on purpuse!");
+  }
+
+  passStruct4BytesHomogeneousInt16x10_a0 = a0;
+  passStruct4BytesHomogeneousInt16x10_a1 = a1;
+  passStruct4BytesHomogeneousInt16x10_a2 = a2;
+  passStruct4BytesHomogeneousInt16x10_a3 = a3;
+  passStruct4BytesHomogeneousInt16x10_a4 = a4;
+  passStruct4BytesHomogeneousInt16x10_a5 = a5;
+  passStruct4BytesHomogeneousInt16x10_a6 = a6;
+  passStruct4BytesHomogeneousInt16x10_a7 = a7;
+  passStruct4BytesHomogeneousInt16x10_a8 = a8;
+  passStruct4BytesHomogeneousInt16x10_a9 = a9;
+
+  final result = passStruct4BytesHomogeneousInt16x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct4BytesHomogeneousInt16x10AfterCallback() {
+  final result = passStruct4BytesHomogeneousInt16x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct7BytesIntx10Type = Int64 Function(
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct7BytesInt passStruct7BytesIntx10_a0 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a1 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a2 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a3 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a4 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a5 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a6 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a7 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a8 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a9 = Struct7BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct7BytesIntx10Result = 0;
+
+int passStruct7BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct7BytesIntx10_a0.a0;
+  result += passStruct7BytesIntx10_a0.a1;
+  result += passStruct7BytesIntx10_a0.a2;
+  result += passStruct7BytesIntx10_a1.a0;
+  result += passStruct7BytesIntx10_a1.a1;
+  result += passStruct7BytesIntx10_a1.a2;
+  result += passStruct7BytesIntx10_a2.a0;
+  result += passStruct7BytesIntx10_a2.a1;
+  result += passStruct7BytesIntx10_a2.a2;
+  result += passStruct7BytesIntx10_a3.a0;
+  result += passStruct7BytesIntx10_a3.a1;
+  result += passStruct7BytesIntx10_a3.a2;
+  result += passStruct7BytesIntx10_a4.a0;
+  result += passStruct7BytesIntx10_a4.a1;
+  result += passStruct7BytesIntx10_a4.a2;
+  result += passStruct7BytesIntx10_a5.a0;
+  result += passStruct7BytesIntx10_a5.a1;
+  result += passStruct7BytesIntx10_a5.a2;
+  result += passStruct7BytesIntx10_a6.a0;
+  result += passStruct7BytesIntx10_a6.a1;
+  result += passStruct7BytesIntx10_a6.a2;
+  result += passStruct7BytesIntx10_a7.a0;
+  result += passStruct7BytesIntx10_a7.a1;
+  result += passStruct7BytesIntx10_a7.a2;
+  result += passStruct7BytesIntx10_a8.a0;
+  result += passStruct7BytesIntx10_a8.a1;
+  result += passStruct7BytesIntx10_a8.a2;
+  result += passStruct7BytesIntx10_a9.a0;
+  result += passStruct7BytesIntx10_a9.a1;
+  result += passStruct7BytesIntx10_a9.a2;
+
+  passStruct7BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Sub word size on 64 bit architectures.
+/// 10 struct arguments will exhaust available registers.
+int passStruct7BytesIntx10(
+    Struct7BytesInt a0,
+    Struct7BytesInt a1,
+    Struct7BytesInt a2,
+    Struct7BytesInt a3,
+    Struct7BytesInt a4,
+    Struct7BytesInt a5,
+    Struct7BytesInt a6,
+    Struct7BytesInt a7,
+    Struct7BytesInt a8,
+    Struct7BytesInt a9) {
+  print(
+      "passStruct7BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct7BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct7BytesIntx10_a0 = a0;
+  passStruct7BytesIntx10_a1 = a1;
+  passStruct7BytesIntx10_a2 = a2;
+  passStruct7BytesIntx10_a3 = a3;
+  passStruct7BytesIntx10_a4 = a4;
+  passStruct7BytesIntx10_a5 = a5;
+  passStruct7BytesIntx10_a6 = a6;
+  passStruct7BytesIntx10_a7 = a7;
+  passStruct7BytesIntx10_a8 = a8;
+  passStruct7BytesIntx10_a9 = a9;
+
+  final result = passStruct7BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct7BytesIntx10AfterCallback() {
+  final result = passStruct7BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(15, result);
+}
+
+typedef PassStruct8BytesIntx10Type = Int64 Function(
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesInt passStruct8BytesIntx10_a0 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a1 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a2 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a3 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a4 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a5 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a6 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a7 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a8 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a9 = Struct8BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct8BytesIntx10Result = 0;
+
+int passStruct8BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct8BytesIntx10_a0.a0;
+  result += passStruct8BytesIntx10_a0.a1;
+  result += passStruct8BytesIntx10_a0.a2;
+  result += passStruct8BytesIntx10_a1.a0;
+  result += passStruct8BytesIntx10_a1.a1;
+  result += passStruct8BytesIntx10_a1.a2;
+  result += passStruct8BytesIntx10_a2.a0;
+  result += passStruct8BytesIntx10_a2.a1;
+  result += passStruct8BytesIntx10_a2.a2;
+  result += passStruct8BytesIntx10_a3.a0;
+  result += passStruct8BytesIntx10_a3.a1;
+  result += passStruct8BytesIntx10_a3.a2;
+  result += passStruct8BytesIntx10_a4.a0;
+  result += passStruct8BytesIntx10_a4.a1;
+  result += passStruct8BytesIntx10_a4.a2;
+  result += passStruct8BytesIntx10_a5.a0;
+  result += passStruct8BytesIntx10_a5.a1;
+  result += passStruct8BytesIntx10_a5.a2;
+  result += passStruct8BytesIntx10_a6.a0;
+  result += passStruct8BytesIntx10_a6.a1;
+  result += passStruct8BytesIntx10_a6.a2;
+  result += passStruct8BytesIntx10_a7.a0;
+  result += passStruct8BytesIntx10_a7.a1;
+  result += passStruct8BytesIntx10_a7.a2;
+  result += passStruct8BytesIntx10_a8.a0;
+  result += passStruct8BytesIntx10_a8.a1;
+  result += passStruct8BytesIntx10_a8.a2;
+  result += passStruct8BytesIntx10_a9.a0;
+  result += passStruct8BytesIntx10_a9.a1;
+  result += passStruct8BytesIntx10_a9.a2;
+
+  passStruct8BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Exactly word size struct on 64bit architectures.
+/// 10 struct arguments will exhaust available registers.
+int passStruct8BytesIntx10(
+    Struct8BytesInt a0,
+    Struct8BytesInt a1,
+    Struct8BytesInt a2,
+    Struct8BytesInt a3,
+    Struct8BytesInt a4,
+    Struct8BytesInt a5,
+    Struct8BytesInt a6,
+    Struct8BytesInt a7,
+    Struct8BytesInt a8,
+    Struct8BytesInt a9) {
+  print(
+      "passStruct8BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct8BytesIntx10_a0 = a0;
+  passStruct8BytesIntx10_a1 = a1;
+  passStruct8BytesIntx10_a2 = a2;
+  passStruct8BytesIntx10_a3 = a3;
+  passStruct8BytesIntx10_a4 = a4;
+  passStruct8BytesIntx10_a5 = a5;
+  passStruct8BytesIntx10_a6 = a6;
+  passStruct8BytesIntx10_a7 = a7;
+  passStruct8BytesIntx10_a8 = a8;
+  passStruct8BytesIntx10_a9 = a9;
+
+  final result = passStruct8BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesIntx10AfterCallback() {
+  final result = passStruct8BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(15, result);
+}
+
+typedef PassStruct8BytesHomogeneousFloatx10Type = Float Function(
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a0 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a1 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a2 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a3 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a4 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a5 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a6 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a7 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a8 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a9 =
+    Struct8BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct8BytesHomogeneousFloatx10Result = 0.0;
+
+double passStruct8BytesHomogeneousFloatx10CalculateResult() {
+  double result = 0;
+
+  result += passStruct8BytesHomogeneousFloatx10_a0.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a0.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a1.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a1.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a2.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a2.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a3.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a3.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a4.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a4.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a5.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a5.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a6.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a6.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a7.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a7.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a8.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a8.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a9.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a9.a1;
+
+  passStruct8BytesHomogeneousFloatx10Result = result;
+
+  return result;
+}
+
+/// Arguments passed in FP registers as long as they fit.
+/// 10 struct arguments will exhaust available registers.
+double passStruct8BytesHomogeneousFloatx10(
+    Struct8BytesHomogeneousFloat a0,
+    Struct8BytesHomogeneousFloat a1,
+    Struct8BytesHomogeneousFloat a2,
+    Struct8BytesHomogeneousFloat a3,
+    Struct8BytesHomogeneousFloat a4,
+    Struct8BytesHomogeneousFloat a5,
+    Struct8BytesHomogeneousFloat a6,
+    Struct8BytesHomogeneousFloat a7,
+    Struct8BytesHomogeneousFloat a8,
+    Struct8BytesHomogeneousFloat a9) {
+  print(
+      "passStruct8BytesHomogeneousFloatx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesHomogeneousFloatx10 throwing on purpuse!");
+  }
+
+  passStruct8BytesHomogeneousFloatx10_a0 = a0;
+  passStruct8BytesHomogeneousFloatx10_a1 = a1;
+  passStruct8BytesHomogeneousFloatx10_a2 = a2;
+  passStruct8BytesHomogeneousFloatx10_a3 = a3;
+  passStruct8BytesHomogeneousFloatx10_a4 = a4;
+  passStruct8BytesHomogeneousFloatx10_a5 = a5;
+  passStruct8BytesHomogeneousFloatx10_a6 = a6;
+  passStruct8BytesHomogeneousFloatx10_a7 = a7;
+  passStruct8BytesHomogeneousFloatx10_a8 = a8;
+  passStruct8BytesHomogeneousFloatx10_a9 = a9;
+
+  final result = passStruct8BytesHomogeneousFloatx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesHomogeneousFloatx10AfterCallback() {
+  final result = passStruct8BytesHomogeneousFloatx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct8BytesMixedx10Type = Float Function(
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesMixed passStruct8BytesMixedx10_a0 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a1 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a2 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a3 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a4 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a5 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a6 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a7 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a8 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a9 = Struct8BytesMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct8BytesMixedx10Result = 0.0;
+
+double passStruct8BytesMixedx10CalculateResult() {
+  double result = 0;
+
+  result += passStruct8BytesMixedx10_a0.a0;
+  result += passStruct8BytesMixedx10_a0.a1;
+  result += passStruct8BytesMixedx10_a0.a2;
+  result += passStruct8BytesMixedx10_a1.a0;
+  result += passStruct8BytesMixedx10_a1.a1;
+  result += passStruct8BytesMixedx10_a1.a2;
+  result += passStruct8BytesMixedx10_a2.a0;
+  result += passStruct8BytesMixedx10_a2.a1;
+  result += passStruct8BytesMixedx10_a2.a2;
+  result += passStruct8BytesMixedx10_a3.a0;
+  result += passStruct8BytesMixedx10_a3.a1;
+  result += passStruct8BytesMixedx10_a3.a2;
+  result += passStruct8BytesMixedx10_a4.a0;
+  result += passStruct8BytesMixedx10_a4.a1;
+  result += passStruct8BytesMixedx10_a4.a2;
+  result += passStruct8BytesMixedx10_a5.a0;
+  result += passStruct8BytesMixedx10_a5.a1;
+  result += passStruct8BytesMixedx10_a5.a2;
+  result += passStruct8BytesMixedx10_a6.a0;
+  result += passStruct8BytesMixedx10_a6.a1;
+  result += passStruct8BytesMixedx10_a6.a2;
+  result += passStruct8BytesMixedx10_a7.a0;
+  result += passStruct8BytesMixedx10_a7.a1;
+  result += passStruct8BytesMixedx10_a7.a2;
+  result += passStruct8BytesMixedx10_a8.a0;
+  result += passStruct8BytesMixedx10_a8.a1;
+  result += passStruct8BytesMixedx10_a8.a2;
+  result += passStruct8BytesMixedx10_a9.a0;
+  result += passStruct8BytesMixedx10_a9.a1;
+  result += passStruct8BytesMixedx10_a9.a2;
+
+  passStruct8BytesMixedx10Result = result;
+
+  return result;
+}
+
+/// On x64, arguments go in int registers because it is not only float.
+/// 10 struct arguments will exhaust available registers.
+double passStruct8BytesMixedx10(
+    Struct8BytesMixed a0,
+    Struct8BytesMixed a1,
+    Struct8BytesMixed a2,
+    Struct8BytesMixed a3,
+    Struct8BytesMixed a4,
+    Struct8BytesMixed a5,
+    Struct8BytesMixed a6,
+    Struct8BytesMixed a7,
+    Struct8BytesMixed a8,
+    Struct8BytesMixed a9) {
+  print(
+      "passStruct8BytesMixedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesMixedx10 throwing on purpuse!");
+  }
+
+  passStruct8BytesMixedx10_a0 = a0;
+  passStruct8BytesMixedx10_a1 = a1;
+  passStruct8BytesMixedx10_a2 = a2;
+  passStruct8BytesMixedx10_a3 = a3;
+  passStruct8BytesMixedx10_a4 = a4;
+  passStruct8BytesMixedx10_a5 = a5;
+  passStruct8BytesMixedx10_a6 = a6;
+  passStruct8BytesMixedx10_a7 = a7;
+  passStruct8BytesMixedx10_a8 = a8;
+  passStruct8BytesMixedx10_a9 = a9;
+
+  final result = passStruct8BytesMixedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesMixedx10AfterCallback() {
+  final result = passStruct8BytesMixedx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(15.0, result);
+}
+
+typedef PassStruct9BytesIntx10Type = Int64 Function(
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesInt passStruct9BytesIntx10_a0 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a1 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a2 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a3 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a4 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a5 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a6 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a7 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a8 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a9 = Struct9BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct9BytesIntx10Result = 0;
+
+int passStruct9BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct9BytesIntx10_a0.a0;
+  result += passStruct9BytesIntx10_a0.a1;
+  result += passStruct9BytesIntx10_a1.a0;
+  result += passStruct9BytesIntx10_a1.a1;
+  result += passStruct9BytesIntx10_a2.a0;
+  result += passStruct9BytesIntx10_a2.a1;
+  result += passStruct9BytesIntx10_a3.a0;
+  result += passStruct9BytesIntx10_a3.a1;
+  result += passStruct9BytesIntx10_a4.a0;
+  result += passStruct9BytesIntx10_a4.a1;
+  result += passStruct9BytesIntx10_a5.a0;
+  result += passStruct9BytesIntx10_a5.a1;
+  result += passStruct9BytesIntx10_a6.a0;
+  result += passStruct9BytesIntx10_a6.a1;
+  result += passStruct9BytesIntx10_a7.a0;
+  result += passStruct9BytesIntx10_a7.a1;
+  result += passStruct9BytesIntx10_a8.a0;
+  result += passStruct9BytesIntx10_a8.a1;
+  result += passStruct9BytesIntx10_a9.a0;
+  result += passStruct9BytesIntx10_a9.a1;
+
+  passStruct9BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+int passStruct9BytesIntx10(
+    Struct9BytesInt a0,
+    Struct9BytesInt a1,
+    Struct9BytesInt a2,
+    Struct9BytesInt a3,
+    Struct9BytesInt a4,
+    Struct9BytesInt a5,
+    Struct9BytesInt a6,
+    Struct9BytesInt a7,
+    Struct9BytesInt a8,
+    Struct9BytesInt a9) {
+  print(
+      "passStruct9BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct9BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct9BytesIntx10_a0 = a0;
+  passStruct9BytesIntx10_a1 = a1;
+  passStruct9BytesIntx10_a2 = a2;
+  passStruct9BytesIntx10_a3 = a3;
+  passStruct9BytesIntx10_a4 = a4;
+  passStruct9BytesIntx10_a5 = a5;
+  passStruct9BytesIntx10_a6 = a6;
+  passStruct9BytesIntx10_a7 = a7;
+  passStruct9BytesIntx10_a8 = a8;
+  passStruct9BytesIntx10_a9 = a9;
+
+  final result = passStruct9BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesIntx10AfterCallback() {
+  final result = passStruct9BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct9BytesHomogeneousUint82x10Type = Int64 Function(
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a0 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a1 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a2 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a3 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a4 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a5 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a6 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a7 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a8 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a9 =
+    Struct9BytesHomogeneousUint82();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct9BytesHomogeneousUint82x10Result = 0;
+
+int passStruct9BytesHomogeneousUint82x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct9BytesHomogeneousUint82x10_a0.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a8;
+
+  passStruct9BytesHomogeneousUint82x10Result = result;
+
+  return result;
+}
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Struct only has 1-byte aligned fields to test struct alignment itself.
+///
+int passStruct9BytesHomogeneousUint82x10(
+    Struct9BytesHomogeneousUint82 a0,
+    Struct9BytesHomogeneousUint82 a1,
+    Struct9BytesHomogeneousUint82 a2,
+    Struct9BytesHomogeneousUint82 a3,
+    Struct9BytesHomogeneousUint82 a4,
+    Struct9BytesHomogeneousUint82 a5,
+    Struct9BytesHomogeneousUint82 a6,
+    Struct9BytesHomogeneousUint82 a7,
+    Struct9BytesHomogeneousUint82 a8,
+    Struct9BytesHomogeneousUint82 a9) {
+  print(
+      "passStruct9BytesHomogeneousUint82x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct9BytesHomogeneousUint82x10 throwing on purpuse!");
+  }
+
+  passStruct9BytesHomogeneousUint82x10_a0 = a0;
+  passStruct9BytesHomogeneousUint82x10_a1 = a1;
+  passStruct9BytesHomogeneousUint82x10_a2 = a2;
+  passStruct9BytesHomogeneousUint82x10_a3 = a3;
+  passStruct9BytesHomogeneousUint82x10_a4 = a4;
+  passStruct9BytesHomogeneousUint82x10_a5 = a5;
+  passStruct9BytesHomogeneousUint82x10_a6 = a6;
+  passStruct9BytesHomogeneousUint82x10_a7 = a7;
+  passStruct9BytesHomogeneousUint82x10_a8 = a8;
+  passStruct9BytesHomogeneousUint82x10_a9 = a9;
+
+  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesHomogeneousUint82x10AfterCallback() {
+  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(4095, result);
+}
+
+typedef PassStruct12BytesHomogeneousFloatx6Type = Float Function(
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a0 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a1 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a2 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a3 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a4 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a5 =
+    Struct12BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct12BytesHomogeneousFloatx6Result = 0.0;
+
+double passStruct12BytesHomogeneousFloatx6CalculateResult() {
+  double result = 0;
+
+  result += passStruct12BytesHomogeneousFloatx6_a0.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a0.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a0.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a1.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a1.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a1.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a2.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a2.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a2.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a3.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a3.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a3.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a4.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a4.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a4.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a5.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a5.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a5.a2;
+
+  passStruct12BytesHomogeneousFloatx6Result = result;
+
+  return result;
+}
+
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// Struct arguments will exhaust available registers, and leave some empty.
+/// The last argument is to test whether arguments are backfilled.
+double passStruct12BytesHomogeneousFloatx6(
+    Struct12BytesHomogeneousFloat a0,
+    Struct12BytesHomogeneousFloat a1,
+    Struct12BytesHomogeneousFloat a2,
+    Struct12BytesHomogeneousFloat a3,
+    Struct12BytesHomogeneousFloat a4,
+    Struct12BytesHomogeneousFloat a5) {
+  print(
+      "passStruct12BytesHomogeneousFloatx6(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct12BytesHomogeneousFloatx6 throwing on purpuse!");
+  }
+
+  passStruct12BytesHomogeneousFloatx6_a0 = a0;
+  passStruct12BytesHomogeneousFloatx6_a1 = a1;
+  passStruct12BytesHomogeneousFloatx6_a2 = a2;
+  passStruct12BytesHomogeneousFloatx6_a3 = a3;
+  passStruct12BytesHomogeneousFloatx6_a4 = a4;
+  passStruct12BytesHomogeneousFloatx6_a5 = a5;
+
+  final result = passStruct12BytesHomogeneousFloatx6CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct12BytesHomogeneousFloatx6AfterCallback() {
+  final result = passStruct12BytesHomogeneousFloatx6CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(9.0, result);
+}
+
+typedef PassStruct16BytesHomogeneousFloatx5Type = Float Function(
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a0 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a1 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a2 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a3 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a4 =
+    Struct16BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct16BytesHomogeneousFloatx5Result = 0.0;
+
+double passStruct16BytesHomogeneousFloatx5CalculateResult() {
+  double result = 0;
+
+  result += passStruct16BytesHomogeneousFloatx5_a0.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a0.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a0.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a0.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a3;
+
+  passStruct16BytesHomogeneousFloatx5Result = result;
+
+  return result;
+}
+
+/// On Linux x64 argument is transferred on stack because it is over 16 bytes.
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// 5 struct arguments will exhaust available registers.
+double passStruct16BytesHomogeneousFloatx5(
+    Struct16BytesHomogeneousFloat a0,
+    Struct16BytesHomogeneousFloat a1,
+    Struct16BytesHomogeneousFloat a2,
+    Struct16BytesHomogeneousFloat a3,
+    Struct16BytesHomogeneousFloat a4) {
+  print(
+      "passStruct16BytesHomogeneousFloatx5(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct16BytesHomogeneousFloatx5 throwing on purpuse!");
+  }
+
+  passStruct16BytesHomogeneousFloatx5_a0 = a0;
+  passStruct16BytesHomogeneousFloatx5_a1 = a1;
+  passStruct16BytesHomogeneousFloatx5_a2 = a2;
+  passStruct16BytesHomogeneousFloatx5_a3 = a3;
+  passStruct16BytesHomogeneousFloatx5_a4 = a4;
+
+  final result = passStruct16BytesHomogeneousFloatx5CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct16BytesHomogeneousFloatx5AfterCallback() {
+  final result = passStruct16BytesHomogeneousFloatx5CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct16BytesMixedx10Type = Double Function(
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct16BytesMixed passStruct16BytesMixedx10_a0 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a1 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a2 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a3 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a4 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a5 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a6 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a7 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a8 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a9 = Struct16BytesMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct16BytesMixedx10Result = 0.0;
+
+double passStruct16BytesMixedx10CalculateResult() {
+  double result = 0;
+
+  result += passStruct16BytesMixedx10_a0.a0;
+  result += passStruct16BytesMixedx10_a0.a1;
+  result += passStruct16BytesMixedx10_a1.a0;
+  result += passStruct16BytesMixedx10_a1.a1;
+  result += passStruct16BytesMixedx10_a2.a0;
+  result += passStruct16BytesMixedx10_a2.a1;
+  result += passStruct16BytesMixedx10_a3.a0;
+  result += passStruct16BytesMixedx10_a3.a1;
+  result += passStruct16BytesMixedx10_a4.a0;
+  result += passStruct16BytesMixedx10_a4.a1;
+  result += passStruct16BytesMixedx10_a5.a0;
+  result += passStruct16BytesMixedx10_a5.a1;
+  result += passStruct16BytesMixedx10_a6.a0;
+  result += passStruct16BytesMixedx10_a6.a1;
+  result += passStruct16BytesMixedx10_a7.a0;
+  result += passStruct16BytesMixedx10_a7.a1;
+  result += passStruct16BytesMixedx10_a8.a0;
+  result += passStruct16BytesMixedx10_a8.a1;
+  result += passStruct16BytesMixedx10_a9.a0;
+  result += passStruct16BytesMixedx10_a9.a1;
+
+  passStruct16BytesMixedx10Result = result;
+
+  return result;
+}
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 8 byte aligned.
+double passStruct16BytesMixedx10(
+    Struct16BytesMixed a0,
+    Struct16BytesMixed a1,
+    Struct16BytesMixed a2,
+    Struct16BytesMixed a3,
+    Struct16BytesMixed a4,
+    Struct16BytesMixed a5,
+    Struct16BytesMixed a6,
+    Struct16BytesMixed a7,
+    Struct16BytesMixed a8,
+    Struct16BytesMixed a9) {
+  print(
+      "passStruct16BytesMixedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct16BytesMixedx10 throwing on purpuse!");
+  }
+
+  passStruct16BytesMixedx10_a0 = a0;
+  passStruct16BytesMixedx10_a1 = a1;
+  passStruct16BytesMixedx10_a2 = a2;
+  passStruct16BytesMixedx10_a3 = a3;
+  passStruct16BytesMixedx10_a4 = a4;
+  passStruct16BytesMixedx10_a5 = a5;
+  passStruct16BytesMixedx10_a6 = a6;
+  passStruct16BytesMixedx10_a7 = a7;
+  passStruct16BytesMixedx10_a8 = a8;
+  passStruct16BytesMixedx10_a9 = a9;
+
+  final result = passStruct16BytesMixedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct16BytesMixedx10AfterCallback() {
+  final result = passStruct16BytesMixedx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct16BytesMixed2x10Type = Float Function(
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2);
+
+// Global variables to be able to test inputs after callback returned.
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a0 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a1 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a2 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a3 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a4 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a5 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a6 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a7 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a8 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a9 = Struct16BytesMixed2();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct16BytesMixed2x10Result = 0.0;
+
+double passStruct16BytesMixed2x10CalculateResult() {
+  double result = 0;
+
+  result += passStruct16BytesMixed2x10_a0.a0;
+  result += passStruct16BytesMixed2x10_a0.a1;
+  result += passStruct16BytesMixed2x10_a0.a2;
+  result += passStruct16BytesMixed2x10_a0.a3;
+  result += passStruct16BytesMixed2x10_a1.a0;
+  result += passStruct16BytesMixed2x10_a1.a1;
+  result += passStruct16BytesMixed2x10_a1.a2;
+  result += passStruct16BytesMixed2x10_a1.a3;
+  result += passStruct16BytesMixed2x10_a2.a0;
+  result += passStruct16BytesMixed2x10_a2.a1;
+  result += passStruct16BytesMixed2x10_a2.a2;
+  result += passStruct16BytesMixed2x10_a2.a3;
+  result += passStruct16BytesMixed2x10_a3.a0;
+  result += passStruct16BytesMixed2x10_a3.a1;
+  result += passStruct16BytesMixed2x10_a3.a2;
+  result += passStruct16BytesMixed2x10_a3.a3;
+  result += passStruct16BytesMixed2x10_a4.a0;
+  result += passStruct16BytesMixed2x10_a4.a1;
+  result += passStruct16BytesMixed2x10_a4.a2;
+  result += passStruct16BytesMixed2x10_a4.a3;
+  result += passStruct16BytesMixed2x10_a5.a0;
+  result += passStruct16BytesMixed2x10_a5.a1;
+  result += passStruct16BytesMixed2x10_a5.a2;
+  result += passStruct16BytesMixed2x10_a5.a3;
+  result += passStruct16BytesMixed2x10_a6.a0;
+  result += passStruct16BytesMixed2x10_a6.a1;
+  result += passStruct16BytesMixed2x10_a6.a2;
+  result += passStruct16BytesMixed2x10_a6.a3;
+  result += passStruct16BytesMixed2x10_a7.a0;
+  result += passStruct16BytesMixed2x10_a7.a1;
+  result += passStruct16BytesMixed2x10_a7.a2;
+  result += passStruct16BytesMixed2x10_a7.a3;
+  result += passStruct16BytesMixed2x10_a8.a0;
+  result += passStruct16BytesMixed2x10_a8.a1;
+  result += passStruct16BytesMixed2x10_a8.a2;
+  result += passStruct16BytesMixed2x10_a8.a3;
+  result += passStruct16BytesMixed2x10_a9.a0;
+  result += passStruct16BytesMixed2x10_a9.a1;
+  result += passStruct16BytesMixed2x10_a9.a2;
+  result += passStruct16BytesMixed2x10_a9.a3;
+
+  passStruct16BytesMixed2x10Result = result;
+
+  return result;
+}
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 4 byte aligned.
+double passStruct16BytesMixed2x10(
+    Struct16BytesMixed2 a0,
+    Struct16BytesMixed2 a1,
+    Struct16BytesMixed2 a2,
+    Struct16BytesMixed2 a3,
+    Struct16BytesMixed2 a4,
+    Struct16BytesMixed2 a5,
+    Struct16BytesMixed2 a6,
+    Struct16BytesMixed2 a7,
+    Struct16BytesMixed2 a8,
+    Struct16BytesMixed2 a9) {
+  print(
+      "passStruct16BytesMixed2x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct16BytesMixed2x10 throwing on purpuse!");
+  }
+
+  passStruct16BytesMixed2x10_a0 = a0;
+  passStruct16BytesMixed2x10_a1 = a1;
+  passStruct16BytesMixed2x10_a2 = a2;
+  passStruct16BytesMixed2x10_a3 = a3;
+  passStruct16BytesMixed2x10_a4 = a4;
+  passStruct16BytesMixed2x10_a5 = a5;
+  passStruct16BytesMixed2x10_a6 = a6;
+  passStruct16BytesMixed2x10_a7 = a7;
+  passStruct16BytesMixed2x10_a8 = a8;
+  passStruct16BytesMixed2x10_a9 = a9;
+
+  final result = passStruct16BytesMixed2x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct16BytesMixed2x10AfterCallback() {
+  final result = passStruct16BytesMixed2x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(20.0, result);
+}
+
+typedef PassStruct17BytesIntx10Type = Int64 Function(
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct17BytesInt passStruct17BytesIntx10_a0 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a1 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a2 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a3 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a4 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a5 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a6 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a7 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a8 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a9 = Struct17BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct17BytesIntx10Result = 0;
+
+int passStruct17BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct17BytesIntx10_a0.a0;
+  result += passStruct17BytesIntx10_a0.a1;
+  result += passStruct17BytesIntx10_a0.a2;
+  result += passStruct17BytesIntx10_a1.a0;
+  result += passStruct17BytesIntx10_a1.a1;
+  result += passStruct17BytesIntx10_a1.a2;
+  result += passStruct17BytesIntx10_a2.a0;
+  result += passStruct17BytesIntx10_a2.a1;
+  result += passStruct17BytesIntx10_a2.a2;
+  result += passStruct17BytesIntx10_a3.a0;
+  result += passStruct17BytesIntx10_a3.a1;
+  result += passStruct17BytesIntx10_a3.a2;
+  result += passStruct17BytesIntx10_a4.a0;
+  result += passStruct17BytesIntx10_a4.a1;
+  result += passStruct17BytesIntx10_a4.a2;
+  result += passStruct17BytesIntx10_a5.a0;
+  result += passStruct17BytesIntx10_a5.a1;
+  result += passStruct17BytesIntx10_a5.a2;
+  result += passStruct17BytesIntx10_a6.a0;
+  result += passStruct17BytesIntx10_a6.a1;
+  result += passStruct17BytesIntx10_a6.a2;
+  result += passStruct17BytesIntx10_a7.a0;
+  result += passStruct17BytesIntx10_a7.a1;
+  result += passStruct17BytesIntx10_a7.a2;
+  result += passStruct17BytesIntx10_a8.a0;
+  result += passStruct17BytesIntx10_a8.a1;
+  result += passStruct17BytesIntx10_a8.a2;
+  result += passStruct17BytesIntx10_a9.a0;
+  result += passStruct17BytesIntx10_a9.a1;
+  result += passStruct17BytesIntx10_a9.a2;
+
+  passStruct17BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Arguments are passed as pointer to copy on arm64.
+/// Tests that the memory allocated for copies are rounded up to word size.
+int passStruct17BytesIntx10(
+    Struct17BytesInt a0,
+    Struct17BytesInt a1,
+    Struct17BytesInt a2,
+    Struct17BytesInt a3,
+    Struct17BytesInt a4,
+    Struct17BytesInt a5,
+    Struct17BytesInt a6,
+    Struct17BytesInt a7,
+    Struct17BytesInt a8,
+    Struct17BytesInt a9) {
+  print(
+      "passStruct17BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct17BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct17BytesIntx10_a0 = a0;
+  passStruct17BytesIntx10_a1 = a1;
+  passStruct17BytesIntx10_a2 = a2;
+  passStruct17BytesIntx10_a3 = a3;
+  passStruct17BytesIntx10_a4 = a4;
+  passStruct17BytesIntx10_a5 = a5;
+  passStruct17BytesIntx10_a6 = a6;
+  passStruct17BytesIntx10_a7 = a7;
+  passStruct17BytesIntx10_a8 = a8;
+  passStruct17BytesIntx10_a9 = a9;
+
+  final result = passStruct17BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct17BytesIntx10AfterCallback() {
+  final result = passStruct17BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(15, result);
+}
+
+typedef PassStruct19BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8);
+
+// Global variables to be able to test inputs after callback returned.
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a0 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a1 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a2 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a3 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a4 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a5 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a6 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a7 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a8 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a9 =
+    Struct19BytesHomogeneousUint8();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct19BytesHomogeneousUint8x10Result = 0;
+
+int passStruct19BytesHomogeneousUint8x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct19BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a18;
+
+  passStruct19BytesHomogeneousUint8x10Result = result;
+
+  return result;
+}
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is extended to the right size.
+///
+int passStruct19BytesHomogeneousUint8x10(
+    Struct19BytesHomogeneousUint8 a0,
+    Struct19BytesHomogeneousUint8 a1,
+    Struct19BytesHomogeneousUint8 a2,
+    Struct19BytesHomogeneousUint8 a3,
+    Struct19BytesHomogeneousUint8 a4,
+    Struct19BytesHomogeneousUint8 a5,
+    Struct19BytesHomogeneousUint8 a6,
+    Struct19BytesHomogeneousUint8 a7,
+    Struct19BytesHomogeneousUint8 a8,
+    Struct19BytesHomogeneousUint8 a9) {
+  print(
+      "passStruct19BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct19BytesHomogeneousUint8x10 throwing on purpuse!");
+  }
+
+  passStruct19BytesHomogeneousUint8x10_a0 = a0;
+  passStruct19BytesHomogeneousUint8x10_a1 = a1;
+  passStruct19BytesHomogeneousUint8x10_a2 = a2;
+  passStruct19BytesHomogeneousUint8x10_a3 = a3;
+  passStruct19BytesHomogeneousUint8x10_a4 = a4;
+  passStruct19BytesHomogeneousUint8x10_a5 = a5;
+  passStruct19BytesHomogeneousUint8x10_a6 = a6;
+  passStruct19BytesHomogeneousUint8x10_a7 = a7;
+  passStruct19BytesHomogeneousUint8x10_a8 = a8;
+  passStruct19BytesHomogeneousUint8x10_a9 = a9;
+
+  final result = passStruct19BytesHomogeneousUint8x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct19BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct19BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(18145, result);
+}
+
+typedef PassStruct20BytesHomogeneousInt32x10Type = Int32 Function(
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32);
+
+// Global variables to be able to test inputs after callback returned.
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a0 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a1 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a2 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a3 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a4 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a5 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a6 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a7 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a8 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a9 =
+    Struct20BytesHomogeneousInt32();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct20BytesHomogeneousInt32x10Result = 0;
+
+int passStruct20BytesHomogeneousInt32x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct20BytesHomogeneousInt32x10_a0.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a4;
+
+  passStruct20BytesHomogeneousInt32x10Result = result;
+
+  return result;
+}
+
+/// Argument too big to go into integer registers on arm64.
+/// The arguments are passed as pointers to copies.
+/// The amount of arguments exhausts the number of integer registers, such that
+/// pointers to copies are also passed on the stack.
+int passStruct20BytesHomogeneousInt32x10(
+    Struct20BytesHomogeneousInt32 a0,
+    Struct20BytesHomogeneousInt32 a1,
+    Struct20BytesHomogeneousInt32 a2,
+    Struct20BytesHomogeneousInt32 a3,
+    Struct20BytesHomogeneousInt32 a4,
+    Struct20BytesHomogeneousInt32 a5,
+    Struct20BytesHomogeneousInt32 a6,
+    Struct20BytesHomogeneousInt32 a7,
+    Struct20BytesHomogeneousInt32 a8,
+    Struct20BytesHomogeneousInt32 a9) {
+  print(
+      "passStruct20BytesHomogeneousInt32x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct20BytesHomogeneousInt32x10 throwing on purpuse!");
+  }
+
+  passStruct20BytesHomogeneousInt32x10_a0 = a0;
+  passStruct20BytesHomogeneousInt32x10_a1 = a1;
+  passStruct20BytesHomogeneousInt32x10_a2 = a2;
+  passStruct20BytesHomogeneousInt32x10_a3 = a3;
+  passStruct20BytesHomogeneousInt32x10_a4 = a4;
+  passStruct20BytesHomogeneousInt32x10_a5 = a5;
+  passStruct20BytesHomogeneousInt32x10_a6 = a6;
+  passStruct20BytesHomogeneousInt32x10_a7 = a7;
+  passStruct20BytesHomogeneousInt32x10_a8 = a8;
+  passStruct20BytesHomogeneousInt32x10_a9 = a9;
+
+  final result = passStruct20BytesHomogeneousInt32x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct20BytesHomogeneousInt32x10AfterCallback() {
+  final result = passStruct20BytesHomogeneousInt32x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(25, result);
+}
+
+typedef PassStruct20BytesHomogeneousFloatType = Float Function(
+    Struct20BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct20BytesHomogeneousFloat passStruct20BytesHomogeneousFloat_a0 =
+    Struct20BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct20BytesHomogeneousFloatResult = 0.0;
+
+double passStruct20BytesHomogeneousFloatCalculateResult() {
+  double result = 0;
+
+  result += passStruct20BytesHomogeneousFloat_a0.a0;
+  result += passStruct20BytesHomogeneousFloat_a0.a1;
+  result += passStruct20BytesHomogeneousFloat_a0.a2;
+  result += passStruct20BytesHomogeneousFloat_a0.a3;
+  result += passStruct20BytesHomogeneousFloat_a0.a4;
+
+  passStruct20BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Argument too big to go into FPU registers in hardfp and arm64.
+double passStruct20BytesHomogeneousFloat(Struct20BytesHomogeneousFloat a0) {
+  print("passStruct20BytesHomogeneousFloat(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct20BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  passStruct20BytesHomogeneousFloat_a0 = a0;
+
+  final result = passStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct20BytesHomogeneousFloatAfterCallback() {
+  final result = passStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-3.0, result);
+}
+
+typedef PassStruct32BytesHomogeneousDoublex5Type = Double Function(
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble);
+
+// Global variables to be able to test inputs after callback returned.
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a0 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a1 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a2 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a3 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a4 =
+    Struct32BytesHomogeneousDouble();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct32BytesHomogeneousDoublex5Result = 0.0;
+
+double passStruct32BytesHomogeneousDoublex5CalculateResult() {
+  double result = 0;
+
+  result += passStruct32BytesHomogeneousDoublex5_a0.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a0.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a0.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a0.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a3;
+
+  passStruct32BytesHomogeneousDoublex5Result = result;
+
+  return result;
+}
+
+/// Arguments in FPU registers on arm64.
+/// 5 struct arguments will exhaust available registers.
+double passStruct32BytesHomogeneousDoublex5(
+    Struct32BytesHomogeneousDouble a0,
+    Struct32BytesHomogeneousDouble a1,
+    Struct32BytesHomogeneousDouble a2,
+    Struct32BytesHomogeneousDouble a3,
+    Struct32BytesHomogeneousDouble a4) {
+  print(
+      "passStruct32BytesHomogeneousDoublex5(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct32BytesHomogeneousDoublex5 throwing on purpuse!");
+  }
+
+  passStruct32BytesHomogeneousDoublex5_a0 = a0;
+  passStruct32BytesHomogeneousDoublex5_a1 = a1;
+  passStruct32BytesHomogeneousDoublex5_a2 = a2;
+  passStruct32BytesHomogeneousDoublex5_a3 = a3;
+  passStruct32BytesHomogeneousDoublex5_a4 = a4;
+
+  final result = passStruct32BytesHomogeneousDoublex5CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct32BytesHomogeneousDoublex5AfterCallback() {
+  final result = passStruct32BytesHomogeneousDoublex5CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct40BytesHomogeneousDoubleType = Double Function(
+    Struct40BytesHomogeneousDouble);
+
+// Global variables to be able to test inputs after callback returned.
+Struct40BytesHomogeneousDouble passStruct40BytesHomogeneousDouble_a0 =
+    Struct40BytesHomogeneousDouble();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct40BytesHomogeneousDoubleResult = 0.0;
+
+double passStruct40BytesHomogeneousDoubleCalculateResult() {
+  double result = 0;
+
+  result += passStruct40BytesHomogeneousDouble_a0.a0;
+  result += passStruct40BytesHomogeneousDouble_a0.a1;
+  result += passStruct40BytesHomogeneousDouble_a0.a2;
+  result += passStruct40BytesHomogeneousDouble_a0.a3;
+  result += passStruct40BytesHomogeneousDouble_a0.a4;
+
+  passStruct40BytesHomogeneousDoubleResult = result;
+
+  return result;
+}
+
+/// Argument too big to go into FPU registers in arm64.
+double passStruct40BytesHomogeneousDouble(Struct40BytesHomogeneousDouble a0) {
+  print("passStruct40BytesHomogeneousDouble(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct40BytesHomogeneousDouble throwing on purpuse!");
+  }
+
+  passStruct40BytesHomogeneousDouble_a0 = a0;
+
+  final result = passStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct40BytesHomogeneousDoubleAfterCallback() {
+  final result = passStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-3.0, result);
+}
+
+typedef PassStruct1024BytesHomogeneousUint64Type = Uint64 Function(
+    Struct1024BytesHomogeneousUint64);
+
+// Global variables to be able to test inputs after callback returned.
+Struct1024BytesHomogeneousUint64 passStruct1024BytesHomogeneousUint64_a0 =
+    Struct1024BytesHomogeneousUint64();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct1024BytesHomogeneousUint64Result = 0;
+
+int passStruct1024BytesHomogeneousUint64CalculateResult() {
+  int result = 0;
+
+  result += passStruct1024BytesHomogeneousUint64_a0.a0;
+  result += passStruct1024BytesHomogeneousUint64_a0.a1;
+  result += passStruct1024BytesHomogeneousUint64_a0.a2;
+  result += passStruct1024BytesHomogeneousUint64_a0.a3;
+  result += passStruct1024BytesHomogeneousUint64_a0.a4;
+  result += passStruct1024BytesHomogeneousUint64_a0.a5;
+  result += passStruct1024BytesHomogeneousUint64_a0.a6;
+  result += passStruct1024BytesHomogeneousUint64_a0.a7;
+  result += passStruct1024BytesHomogeneousUint64_a0.a8;
+  result += passStruct1024BytesHomogeneousUint64_a0.a9;
+  result += passStruct1024BytesHomogeneousUint64_a0.a10;
+  result += passStruct1024BytesHomogeneousUint64_a0.a11;
+  result += passStruct1024BytesHomogeneousUint64_a0.a12;
+  result += passStruct1024BytesHomogeneousUint64_a0.a13;
+  result += passStruct1024BytesHomogeneousUint64_a0.a14;
+  result += passStruct1024BytesHomogeneousUint64_a0.a15;
+  result += passStruct1024BytesHomogeneousUint64_a0.a16;
+  result += passStruct1024BytesHomogeneousUint64_a0.a17;
+  result += passStruct1024BytesHomogeneousUint64_a0.a18;
+  result += passStruct1024BytesHomogeneousUint64_a0.a19;
+  result += passStruct1024BytesHomogeneousUint64_a0.a20;
+  result += passStruct1024BytesHomogeneousUint64_a0.a21;
+  result += passStruct1024BytesHomogeneousUint64_a0.a22;
+  result += passStruct1024BytesHomogeneousUint64_a0.a23;
+  result += passStruct1024BytesHomogeneousUint64_a0.a24;
+  result += passStruct1024BytesHomogeneousUint64_a0.a25;
+  result += passStruct1024BytesHomogeneousUint64_a0.a26;
+  result += passStruct1024BytesHomogeneousUint64_a0.a27;
+  result += passStruct1024BytesHomogeneousUint64_a0.a28;
+  result += passStruct1024BytesHomogeneousUint64_a0.a29;
+  result += passStruct1024BytesHomogeneousUint64_a0.a30;
+  result += passStruct1024BytesHomogeneousUint64_a0.a31;
+  result += passStruct1024BytesHomogeneousUint64_a0.a32;
+  result += passStruct1024BytesHomogeneousUint64_a0.a33;
+  result += passStruct1024BytesHomogeneousUint64_a0.a34;
+  result += passStruct1024BytesHomogeneousUint64_a0.a35;
+  result += passStruct1024BytesHomogeneousUint64_a0.a36;
+  result += passStruct1024BytesHomogeneousUint64_a0.a37;
+  result += passStruct1024BytesHomogeneousUint64_a0.a38;
+  result += passStruct1024BytesHomogeneousUint64_a0.a39;
+  result += passStruct1024BytesHomogeneousUint64_a0.a40;
+  result += passStruct1024BytesHomogeneousUint64_a0.a41;
+  result += passStruct1024BytesHomogeneousUint64_a0.a42;
+  result += passStruct1024BytesHomogeneousUint64_a0.a43;
+  result += passStruct1024BytesHomogeneousUint64_a0.a44;
+  result += passStruct1024BytesHomogeneousUint64_a0.a45;
+  result += passStruct1024BytesHomogeneousUint64_a0.a46;
+  result += passStruct1024BytesHomogeneousUint64_a0.a47;
+  result += passStruct1024BytesHomogeneousUint64_a0.a48;
+  result += passStruct1024BytesHomogeneousUint64_a0.a49;
+  result += passStruct1024BytesHomogeneousUint64_a0.a50;
+  result += passStruct1024BytesHomogeneousUint64_a0.a51;
+  result += passStruct1024BytesHomogeneousUint64_a0.a52;
+  result += passStruct1024BytesHomogeneousUint64_a0.a53;
+  result += passStruct1024BytesHomogeneousUint64_a0.a54;
+  result += passStruct1024BytesHomogeneousUint64_a0.a55;
+  result += passStruct1024BytesHomogeneousUint64_a0.a56;
+  result += passStruct1024BytesHomogeneousUint64_a0.a57;
+  result += passStruct1024BytesHomogeneousUint64_a0.a58;
+  result += passStruct1024BytesHomogeneousUint64_a0.a59;
+  result += passStruct1024BytesHomogeneousUint64_a0.a60;
+  result += passStruct1024BytesHomogeneousUint64_a0.a61;
+  result += passStruct1024BytesHomogeneousUint64_a0.a62;
+  result += passStruct1024BytesHomogeneousUint64_a0.a63;
+  result += passStruct1024BytesHomogeneousUint64_a0.a64;
+  result += passStruct1024BytesHomogeneousUint64_a0.a65;
+  result += passStruct1024BytesHomogeneousUint64_a0.a66;
+  result += passStruct1024BytesHomogeneousUint64_a0.a67;
+  result += passStruct1024BytesHomogeneousUint64_a0.a68;
+  result += passStruct1024BytesHomogeneousUint64_a0.a69;
+  result += passStruct1024BytesHomogeneousUint64_a0.a70;
+  result += passStruct1024BytesHomogeneousUint64_a0.a71;
+  result += passStruct1024BytesHomogeneousUint64_a0.a72;
+  result += passStruct1024BytesHomogeneousUint64_a0.a73;
+  result += passStruct1024BytesHomogeneousUint64_a0.a74;
+  result += passStruct1024BytesHomogeneousUint64_a0.a75;
+  result += passStruct1024BytesHomogeneousUint64_a0.a76;
+  result += passStruct1024BytesHomogeneousUint64_a0.a77;
+  result += passStruct1024BytesHomogeneousUint64_a0.a78;
+  result += passStruct1024BytesHomogeneousUint64_a0.a79;
+  result += passStruct1024BytesHomogeneousUint64_a0.a80;
+  result += passStruct1024BytesHomogeneousUint64_a0.a81;
+  result += passStruct1024BytesHomogeneousUint64_a0.a82;
+  result += passStruct1024BytesHomogeneousUint64_a0.a83;
+  result += passStruct1024BytesHomogeneousUint64_a0.a84;
+  result += passStruct1024BytesHomogeneousUint64_a0.a85;
+  result += passStruct1024BytesHomogeneousUint64_a0.a86;
+  result += passStruct1024BytesHomogeneousUint64_a0.a87;
+  result += passStruct1024BytesHomogeneousUint64_a0.a88;
+  result += passStruct1024BytesHomogeneousUint64_a0.a89;
+  result += passStruct1024BytesHomogeneousUint64_a0.a90;
+  result += passStruct1024BytesHomogeneousUint64_a0.a91;
+  result += passStruct1024BytesHomogeneousUint64_a0.a92;
+  result += passStruct1024BytesHomogeneousUint64_a0.a93;
+  result += passStruct1024BytesHomogeneousUint64_a0.a94;
+  result += passStruct1024BytesHomogeneousUint64_a0.a95;
+  result += passStruct1024BytesHomogeneousUint64_a0.a96;
+  result += passStruct1024BytesHomogeneousUint64_a0.a97;
+  result += passStruct1024BytesHomogeneousUint64_a0.a98;
+  result += passStruct1024BytesHomogeneousUint64_a0.a99;
+  result += passStruct1024BytesHomogeneousUint64_a0.a100;
+  result += passStruct1024BytesHomogeneousUint64_a0.a101;
+  result += passStruct1024BytesHomogeneousUint64_a0.a102;
+  result += passStruct1024BytesHomogeneousUint64_a0.a103;
+  result += passStruct1024BytesHomogeneousUint64_a0.a104;
+  result += passStruct1024BytesHomogeneousUint64_a0.a105;
+  result += passStruct1024BytesHomogeneousUint64_a0.a106;
+  result += passStruct1024BytesHomogeneousUint64_a0.a107;
+  result += passStruct1024BytesHomogeneousUint64_a0.a108;
+  result += passStruct1024BytesHomogeneousUint64_a0.a109;
+  result += passStruct1024BytesHomogeneousUint64_a0.a110;
+  result += passStruct1024BytesHomogeneousUint64_a0.a111;
+  result += passStruct1024BytesHomogeneousUint64_a0.a112;
+  result += passStruct1024BytesHomogeneousUint64_a0.a113;
+  result += passStruct1024BytesHomogeneousUint64_a0.a114;
+  result += passStruct1024BytesHomogeneousUint64_a0.a115;
+  result += passStruct1024BytesHomogeneousUint64_a0.a116;
+  result += passStruct1024BytesHomogeneousUint64_a0.a117;
+  result += passStruct1024BytesHomogeneousUint64_a0.a118;
+  result += passStruct1024BytesHomogeneousUint64_a0.a119;
+  result += passStruct1024BytesHomogeneousUint64_a0.a120;
+  result += passStruct1024BytesHomogeneousUint64_a0.a121;
+  result += passStruct1024BytesHomogeneousUint64_a0.a122;
+  result += passStruct1024BytesHomogeneousUint64_a0.a123;
+  result += passStruct1024BytesHomogeneousUint64_a0.a124;
+  result += passStruct1024BytesHomogeneousUint64_a0.a125;
+  result += passStruct1024BytesHomogeneousUint64_a0.a126;
+  result += passStruct1024BytesHomogeneousUint64_a0.a127;
+
+  passStruct1024BytesHomogeneousUint64Result = result;
+
+  return result;
+}
+
+/// Test 1kb struct.
+int passStruct1024BytesHomogeneousUint64(Struct1024BytesHomogeneousUint64 a0) {
+  print("passStruct1024BytesHomogeneousUint64(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct1024BytesHomogeneousUint64 throwing on purpuse!");
+  }
+
+  passStruct1024BytesHomogeneousUint64_a0 = a0;
+
+  final result = passStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct1024BytesHomogeneousUint64AfterCallback() {
+  final result = passStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(8256, result);
+}
+
+typedef PassFloatStruct16BytesHomogeneousFloatFloatStruct1Type = Float Function(
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float);
+
+// Global variables to be able to test inputs after callback returned.
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a0 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a2 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a4 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a6 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a8 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1Result = 0.0;
+
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1CalculateResult() {
+  double result = 0;
+
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a4;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a6;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a8;
+
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1Result = result;
+
+  return result;
+}
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1(
+    double a0,
+    Struct16BytesHomogeneousFloat a1,
+    double a2,
+    Struct16BytesHomogeneousFloat a3,
+    double a4,
+    Struct16BytesHomogeneousFloat a5,
+    double a6,
+    Struct16BytesHomogeneousFloat a7,
+    double a8) {
+  print(
+      "passFloatStruct16BytesHomogeneousFloatFloatStruct1(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassFloatStruct16BytesHomogeneousFloatFloatStruct1 throwing on purpuse!");
+  }
+
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a0 = a0;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1 = a1;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a2 = a2;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3 = a3;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a4 = a4;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5 = a5;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a6 = a6;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7 = a7;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a8 = a8;
+
+  final result =
+      passFloatStruct16BytesHomogeneousFloatFloatStruct1CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passFloatStruct16BytesHomogeneousFloatFloatStruct1AfterCallback() {
+  final result =
+      passFloatStruct16BytesHomogeneousFloatFloatStruct1CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-11.0, result);
+}
+
+typedef PassFloatStruct32BytesHomogeneousDoubleFloatStructType
+    = Double Function(
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float);
+
+// Global variables to be able to test inputs after callback returned.
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a0 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a2 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a4 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a6 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a8 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+double passFloatStruct32BytesHomogeneousDoubleFloatStructResult = 0.0;
+
+double passFloatStruct32BytesHomogeneousDoubleFloatStructCalculateResult() {
+  double result = 0;
+
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a4;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a6;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a8;
+
+  passFloatStruct32BytesHomogeneousDoubleFloatStructResult = result;
+
+  return result;
+}
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct(
+    double a0,
+    Struct32BytesHomogeneousDouble a1,
+    double a2,
+    Struct32BytesHomogeneousDouble a3,
+    double a4,
+    Struct32BytesHomogeneousDouble a5,
+    double a6,
+    Struct32BytesHomogeneousDouble a7,
+    double a8) {
+  print(
+      "passFloatStruct32BytesHomogeneousDoubleFloatStruct(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassFloatStruct32BytesHomogeneousDoubleFloatStruct throwing on purpuse!");
+  }
+
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a0 = a0;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1 = a1;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a2 = a2;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3 = a3;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a4 = a4;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5 = a5;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a6 = a6;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7 = a7;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a8 = a8;
+
+  final result =
+      passFloatStruct32BytesHomogeneousDoubleFloatStructCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passFloatStruct32BytesHomogeneousDoubleFloatStructAfterCallback() {
+  final result =
+      passFloatStruct32BytesHomogeneousDoubleFloatStructCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-11.0, result);
+}
+
+typedef PassInt8Struct16BytesMixedInt8Struct16BytesMixedInType
+    = Double Function(Int8, Struct16BytesMixed, Int8, Struct16BytesMixed, Int8,
+        Struct16BytesMixed, Int8, Struct16BytesMixed, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a0 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a2 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a4 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a6 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a8 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+double passInt8Struct16BytesMixedInt8Struct16BytesMixedInResult = 0.0;
+
+double passInt8Struct16BytesMixedInt8Struct16BytesMixedInCalculateResult() {
+  double result = 0;
+
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a2;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a4;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a6;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a8;
+
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedInResult = result;
+
+  return result;
+}
+
+/// Tests the alignment of structs in integers registers and on the stack.
+/// Arm32 aligns this struct at 8.
+/// Also, arm32 allocates the second struct partially in registers, partially
+/// on stack.
+/// Test backfilling of integer registers.
+double passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
+    int a0,
+    Struct16BytesMixed a1,
+    int a2,
+    Struct16BytesMixed a3,
+    int a4,
+    Struct16BytesMixed a5,
+    int a6,
+    Struct16BytesMixed a7,
+    int a8) {
+  print(
+      "passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn throwing on purpuse!");
+  }
+
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a0 = a0;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1 = a1;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a2 = a2;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3 = a3;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a4 = a4;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5 = a5;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a6 = a6;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7 = a7;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a8 = a8;
+
+  final result =
+      passInt8Struct16BytesMixedInt8Struct16BytesMixedInCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passInt8Struct16BytesMixedInt8Struct16BytesMixedInAfterCallback() {
+  final result =
+      passInt8Struct16BytesMixedInt8Struct16BytesMixedInCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-7.0, result);
+}
+
+typedef PassDoublex6Struct16BytesMixedx4Int32Type = Double Function(
+    Double,
+    Double,
+    Double,
+    Double,
+    Double,
+    Double,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Int32);
+
+// Global variables to be able to test inputs after callback returned.
+double passDoublex6Struct16BytesMixedx4Int32_a0 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a1 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a2 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a3 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a4 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a5 = 0.0;
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a6 =
+    Struct16BytesMixed();
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a7 =
+    Struct16BytesMixed();
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a8 =
+    Struct16BytesMixed();
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a9 =
+    Struct16BytesMixed();
+int passDoublex6Struct16BytesMixedx4Int32_a10 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+double passDoublex6Struct16BytesMixedx4Int32Result = 0.0;
+
+double passDoublex6Struct16BytesMixedx4Int32CalculateResult() {
+  double result = 0;
+
+  result += passDoublex6Struct16BytesMixedx4Int32_a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a2;
+  result += passDoublex6Struct16BytesMixedx4Int32_a3;
+  result += passDoublex6Struct16BytesMixedx4Int32_a4;
+  result += passDoublex6Struct16BytesMixedx4Int32_a5;
+  result += passDoublex6Struct16BytesMixedx4Int32_a6.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a6.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a7.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a7.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a8.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a8.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a9.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a9.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a10;
+
+  passDoublex6Struct16BytesMixedx4Int32Result = result;
+
+  return result;
+}
+
+/// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+/// structs. The rest of the structs will go on the stack.
+/// The int will be backfilled into the int register.
+double passDoublex6Struct16BytesMixedx4Int32(
+    double a0,
+    double a1,
+    double a2,
+    double a3,
+    double a4,
+    double a5,
+    Struct16BytesMixed a6,
+    Struct16BytesMixed a7,
+    Struct16BytesMixed a8,
+    Struct16BytesMixed a9,
+    int a10) {
+  print(
+      "passDoublex6Struct16BytesMixedx4Int32(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassDoublex6Struct16BytesMixedx4Int32 throwing on purpuse!");
+  }
+
+  passDoublex6Struct16BytesMixedx4Int32_a0 = a0;
+  passDoublex6Struct16BytesMixedx4Int32_a1 = a1;
+  passDoublex6Struct16BytesMixedx4Int32_a2 = a2;
+  passDoublex6Struct16BytesMixedx4Int32_a3 = a3;
+  passDoublex6Struct16BytesMixedx4Int32_a4 = a4;
+  passDoublex6Struct16BytesMixedx4Int32_a5 = a5;
+  passDoublex6Struct16BytesMixedx4Int32_a6 = a6;
+  passDoublex6Struct16BytesMixedx4Int32_a7 = a7;
+  passDoublex6Struct16BytesMixedx4Int32_a8 = a8;
+  passDoublex6Struct16BytesMixedx4Int32_a9 = a9;
+  passDoublex6Struct16BytesMixedx4Int32_a10 = a10;
+
+  final result = passDoublex6Struct16BytesMixedx4Int32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passDoublex6Struct16BytesMixedx4Int32AfterCallback() {
+  final result = passDoublex6Struct16BytesMixedx4Int32CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-8.0, result);
+}
+
+typedef PassInt32x4Struct16BytesMixedx4DoubleType = Double Function(
+    Int32,
+    Int32,
+    Int32,
+    Int32,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Double);
+
+// Global variables to be able to test inputs after callback returned.
+int passInt32x4Struct16BytesMixedx4Double_a0 = 0;
+int passInt32x4Struct16BytesMixedx4Double_a1 = 0;
+int passInt32x4Struct16BytesMixedx4Double_a2 = 0;
+int passInt32x4Struct16BytesMixedx4Double_a3 = 0;
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a4 =
+    Struct16BytesMixed();
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a5 =
+    Struct16BytesMixed();
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a6 =
+    Struct16BytesMixed();
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a7 =
+    Struct16BytesMixed();
+double passInt32x4Struct16BytesMixedx4Double_a8 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+double passInt32x4Struct16BytesMixedx4DoubleResult = 0.0;
+
+double passInt32x4Struct16BytesMixedx4DoubleCalculateResult() {
+  double result = 0;
+
+  result += passInt32x4Struct16BytesMixedx4Double_a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a2;
+  result += passInt32x4Struct16BytesMixedx4Double_a3;
+  result += passInt32x4Struct16BytesMixedx4Double_a4.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a4.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a5.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a5.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a6.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a6.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a7.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a7.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a8;
+
+  passInt32x4Struct16BytesMixedx4DoubleResult = result;
+
+  return result;
+}
+
+/// On Linux x64, it will exhaust int registers first.
+/// The rest of the structs will go on the stack.
+/// The double will be backfilled into the xmm register.
+double passInt32x4Struct16BytesMixedx4Double(
+    int a0,
+    int a1,
+    int a2,
+    int a3,
+    Struct16BytesMixed a4,
+    Struct16BytesMixed a5,
+    Struct16BytesMixed a6,
+    Struct16BytesMixed a7,
+    double a8) {
+  print(
+      "passInt32x4Struct16BytesMixedx4Double(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassInt32x4Struct16BytesMixedx4Double throwing on purpuse!");
+  }
+
+  passInt32x4Struct16BytesMixedx4Double_a0 = a0;
+  passInt32x4Struct16BytesMixedx4Double_a1 = a1;
+  passInt32x4Struct16BytesMixedx4Double_a2 = a2;
+  passInt32x4Struct16BytesMixedx4Double_a3 = a3;
+  passInt32x4Struct16BytesMixedx4Double_a4 = a4;
+  passInt32x4Struct16BytesMixedx4Double_a5 = a5;
+  passInt32x4Struct16BytesMixedx4Double_a6 = a6;
+  passInt32x4Struct16BytesMixedx4Double_a7 = a7;
+  passInt32x4Struct16BytesMixedx4Double_a8 = a8;
+
+  final result = passInt32x4Struct16BytesMixedx4DoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passInt32x4Struct16BytesMixedx4DoubleAfterCallback() {
+  final result = passInt32x4Struct16BytesMixedx4DoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-7.0, result);
+}
+
+typedef PassStruct40BytesHomogeneousDoubleStruct4BytesHomoType
+    = Double Function(Struct40BytesHomogeneousDouble,
+        Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct40BytesHomogeneousDouble
+    passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0 =
+    Struct40BytesHomogeneousDouble();
+Struct4BytesHomogeneousInt16
+    passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1 =
+    Struct4BytesHomogeneousInt16();
+Struct8BytesHomogeneousFloat
+    passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2 =
+    Struct8BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct40BytesHomogeneousDoubleStruct4BytesHomoResult = 0.0;
+
+double passStruct40BytesHomogeneousDoubleStruct4BytesHomoCalculateResult() {
+  double result = 0;
+
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a0;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a1;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a2;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a3;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a4;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1.a0;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1.a1;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2.a0;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2.a1;
+
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomoResult = result;
+
+  return result;
+}
+
+/// On various architectures, first struct is allocated on stack.
+/// Check that the other two arguments are allocated on registers.
+double passStruct40BytesHomogeneousDoubleStruct4BytesHomo(
+    Struct40BytesHomogeneousDouble a0,
+    Struct4BytesHomogeneousInt16 a1,
+    Struct8BytesHomogeneousFloat a2) {
+  print(
+      "passStruct40BytesHomogeneousDoubleStruct4BytesHomo(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo throwing on purpuse!");
+  }
+
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0 = a0;
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1 = a1;
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2 = a2;
+
+  final result =
+      passStruct40BytesHomogeneousDoubleStruct4BytesHomoCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback() {
+  final result =
+      passStruct40BytesHomogeneousDoubleStruct4BytesHomoCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-5.0, result);
+}
+
+typedef PassStructAlignmentInt16Type = Int64 Function(StructAlignmentInt16);
+
+// Global variables to be able to test inputs after callback returned.
+StructAlignmentInt16 passStructAlignmentInt16_a0 = StructAlignmentInt16();
+
+// Result variable also global, so we can delete it after the callback.
+int passStructAlignmentInt16Result = 0;
+
+int passStructAlignmentInt16CalculateResult() {
+  int result = 0;
+
+  result += passStructAlignmentInt16_a0.a0;
+  result += passStructAlignmentInt16_a0.a1;
+  result += passStructAlignmentInt16_a0.a2;
+
+  passStructAlignmentInt16Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 16 byte int within struct.
+int passStructAlignmentInt16(StructAlignmentInt16 a0) {
+  print("passStructAlignmentInt16(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStructAlignmentInt16 throwing on purpuse!");
+  }
+
+  passStructAlignmentInt16_a0 = a0;
+
+  final result = passStructAlignmentInt16CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructAlignmentInt16AfterCallback() {
+  final result = passStructAlignmentInt16CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(-2, result);
+}
+
+typedef PassStructAlignmentInt32Type = Int64 Function(StructAlignmentInt32);
+
+// Global variables to be able to test inputs after callback returned.
+StructAlignmentInt32 passStructAlignmentInt32_a0 = StructAlignmentInt32();
+
+// Result variable also global, so we can delete it after the callback.
+int passStructAlignmentInt32Result = 0;
+
+int passStructAlignmentInt32CalculateResult() {
+  int result = 0;
+
+  result += passStructAlignmentInt32_a0.a0;
+  result += passStructAlignmentInt32_a0.a1;
+  result += passStructAlignmentInt32_a0.a2;
+
+  passStructAlignmentInt32Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 32 byte int within struct.
+int passStructAlignmentInt32(StructAlignmentInt32 a0) {
+  print("passStructAlignmentInt32(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStructAlignmentInt32 throwing on purpuse!");
+  }
+
+  passStructAlignmentInt32_a0 = a0;
+
+  final result = passStructAlignmentInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructAlignmentInt32AfterCallback() {
+  final result = passStructAlignmentInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(-2, result);
+}
+
+typedef PassStructAlignmentInt64Type = Int64 Function(StructAlignmentInt64);
+
+// Global variables to be able to test inputs after callback returned.
+StructAlignmentInt64 passStructAlignmentInt64_a0 = StructAlignmentInt64();
+
+// Result variable also global, so we can delete it after the callback.
+int passStructAlignmentInt64Result = 0;
+
+int passStructAlignmentInt64CalculateResult() {
+  int result = 0;
+
+  result += passStructAlignmentInt64_a0.a0;
+  result += passStructAlignmentInt64_a0.a1;
+  result += passStructAlignmentInt64_a0.a2;
+
+  passStructAlignmentInt64Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 64 byte int within struct.
+int passStructAlignmentInt64(StructAlignmentInt64 a0) {
+  print("passStructAlignmentInt64(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStructAlignmentInt64 throwing on purpuse!");
+  }
+
+  passStructAlignmentInt64_a0 = a0;
+
+  final result = passStructAlignmentInt64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructAlignmentInt64AfterCallback() {
+  final result = passStructAlignmentInt64CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(-2, result);
+}
+
+typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct1ByteInt_a0 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct1ByteInt returnStruct1ByteIntResult = Struct1ByteInt();
+
+Struct1ByteInt returnStruct1ByteIntCalculateResult() {
+  Struct1ByteInt result = allocate<Struct1ByteInt>().ref;
+
+  result.a0 = returnStruct1ByteInt_a0;
+
+  returnStruct1ByteIntResult = result;
+
+  return result;
+}
+
+/// Smallest struct with data.
+Struct1ByteInt returnStruct1ByteInt(int a0) {
+  print("returnStruct1ByteInt(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct1ByteInt throwing on purpuse!");
+  }
+
+  returnStruct1ByteInt_a0 = a0;
+
+  final result = returnStruct1ByteIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct1ByteIntAfterCallback() {
+  free(returnStruct1ByteIntResult.addressOf);
+
+  final result = returnStruct1ByteIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct1ByteIntResult.addressOf);
+}
+
+typedef ReturnStruct3BytesIntType = Struct3BytesInt Function(Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct3BytesInt_a0 = 0;
+int returnStruct3BytesInt_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct3BytesInt returnStruct3BytesIntResult = Struct3BytesInt();
+
+Struct3BytesInt returnStruct3BytesIntCalculateResult() {
+  Struct3BytesInt result = allocate<Struct3BytesInt>().ref;
+
+  result.a0 = returnStruct3BytesInt_a0;
+  result.a1 = returnStruct3BytesInt_a1;
+
+  returnStruct3BytesIntResult = result;
+
+  return result;
+}
+
+/// Smaller than word size return value on all architectures.
+Struct3BytesInt returnStruct3BytesInt(int a0, int a1) {
+  print("returnStruct3BytesInt(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct3BytesInt throwing on purpuse!");
+  }
+
+  returnStruct3BytesInt_a0 = a0;
+  returnStruct3BytesInt_a1 = a1;
+
+  final result = returnStruct3BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct3BytesIntAfterCallback() {
+  free(returnStruct3BytesIntResult.addressOf);
+
+  final result = returnStruct3BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct3BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct4BytesHomogeneousInt16Type = Struct4BytesHomogeneousInt16
+    Function(Int16, Int16);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct4BytesHomogeneousInt16_a0 = 0;
+int returnStruct4BytesHomogeneousInt16_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct4BytesHomogeneousInt16 returnStruct4BytesHomogeneousInt16Result =
+    Struct4BytesHomogeneousInt16();
+
+Struct4BytesHomogeneousInt16
+    returnStruct4BytesHomogeneousInt16CalculateResult() {
+  Struct4BytesHomogeneousInt16 result =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+
+  result.a0 = returnStruct4BytesHomogeneousInt16_a0;
+  result.a1 = returnStruct4BytesHomogeneousInt16_a1;
+
+  returnStruct4BytesHomogeneousInt16Result = result;
+
+  return result;
+}
+
+/// Word size return value on 32 bit architectures..
+Struct4BytesHomogeneousInt16 returnStruct4BytesHomogeneousInt16(
+    int a0, int a1) {
+  print("returnStruct4BytesHomogeneousInt16(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct4BytesHomogeneousInt16 throwing on purpuse!");
+  }
+
+  returnStruct4BytesHomogeneousInt16_a0 = a0;
+  returnStruct4BytesHomogeneousInt16_a1 = a1;
+
+  final result = returnStruct4BytesHomogeneousInt16CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct4BytesHomogeneousInt16AfterCallback() {
+  free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+
+  final result = returnStruct4BytesHomogeneousInt16CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+}
+
+typedef ReturnStruct7BytesIntType = Struct7BytesInt Function(
+    Int32, Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct7BytesInt_a0 = 0;
+int returnStruct7BytesInt_a1 = 0;
+int returnStruct7BytesInt_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct7BytesInt returnStruct7BytesIntResult = Struct7BytesInt();
+
+Struct7BytesInt returnStruct7BytesIntCalculateResult() {
+  Struct7BytesInt result = allocate<Struct7BytesInt>().ref;
+
+  result.a0 = returnStruct7BytesInt_a0;
+  result.a1 = returnStruct7BytesInt_a1;
+  result.a2 = returnStruct7BytesInt_a2;
+
+  returnStruct7BytesIntResult = result;
+
+  return result;
+}
+
+/// Non-wordsize return value.
+Struct7BytesInt returnStruct7BytesInt(int a0, int a1, int a2) {
+  print("returnStruct7BytesInt(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct7BytesInt throwing on purpuse!");
+  }
+
+  returnStruct7BytesInt_a0 = a0;
+  returnStruct7BytesInt_a1 = a1;
+  returnStruct7BytesInt_a2 = a2;
+
+  final result = returnStruct7BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct7BytesIntAfterCallback() {
+  free(returnStruct7BytesIntResult.addressOf);
+
+  final result = returnStruct7BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct7BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct8BytesIntType = Struct8BytesInt Function(
+    Int16, Int16, Int32);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct8BytesInt_a0 = 0;
+int returnStruct8BytesInt_a1 = 0;
+int returnStruct8BytesInt_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesInt returnStruct8BytesIntResult = Struct8BytesInt();
+
+Struct8BytesInt returnStruct8BytesIntCalculateResult() {
+  Struct8BytesInt result = allocate<Struct8BytesInt>().ref;
+
+  result.a0 = returnStruct8BytesInt_a0;
+  result.a1 = returnStruct8BytesInt_a1;
+  result.a2 = returnStruct8BytesInt_a2;
+
+  returnStruct8BytesIntResult = result;
+
+  return result;
+}
+
+/// Return value in integer registers on many architectures.
+Struct8BytesInt returnStruct8BytesInt(int a0, int a1, int a2) {
+  print("returnStruct8BytesInt(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesInt throwing on purpuse!");
+  }
+
+  returnStruct8BytesInt_a0 = a0;
+  returnStruct8BytesInt_a1 = a1;
+  returnStruct8BytesInt_a2 = a2;
+
+  final result = returnStruct8BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesIntAfterCallback() {
+  free(returnStruct8BytesIntResult.addressOf);
+
+  final result = returnStruct8BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct8BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct8BytesHomogeneousFloatType = Struct8BytesHomogeneousFloat
+    Function(Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct8BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct8BytesHomogeneousFloat_a1 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesHomogeneousFloat returnStruct8BytesHomogeneousFloatResult =
+    Struct8BytesHomogeneousFloat();
+
+Struct8BytesHomogeneousFloat
+    returnStruct8BytesHomogeneousFloatCalculateResult() {
+  Struct8BytesHomogeneousFloat result =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct8BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct8BytesHomogeneousFloat_a1;
+
+  returnStruct8BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value in FP registers on many architectures.
+Struct8BytesHomogeneousFloat returnStruct8BytesHomogeneousFloat(
+    double a0, double a1) {
+  print("returnStruct8BytesHomogeneousFloat(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct8BytesHomogeneousFloat_a0 = a0;
+  returnStruct8BytesHomogeneousFloat_a1 = a1;
+
+  final result = returnStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct8BytesMixedType = Struct8BytesMixed Function(
+    Float, Int16, Int16);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct8BytesMixed_a0 = 0.0;
+int returnStruct8BytesMixed_a1 = 0;
+int returnStruct8BytesMixed_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesMixed returnStruct8BytesMixedResult = Struct8BytesMixed();
+
+Struct8BytesMixed returnStruct8BytesMixedCalculateResult() {
+  Struct8BytesMixed result = allocate<Struct8BytesMixed>().ref;
+
+  result.a0 = returnStruct8BytesMixed_a0;
+  result.a1 = returnStruct8BytesMixed_a1;
+  result.a2 = returnStruct8BytesMixed_a2;
+
+  returnStruct8BytesMixedResult = result;
+
+  return result;
+}
+
+/// Return value split over FP and integer register in x64.
+Struct8BytesMixed returnStruct8BytesMixed(double a0, int a1, int a2) {
+  print("returnStruct8BytesMixed(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesMixed throwing on purpuse!");
+  }
+
+  returnStruct8BytesMixed_a0 = a0;
+  returnStruct8BytesMixed_a1 = a1;
+  returnStruct8BytesMixed_a2 = a2;
+
+  final result = returnStruct8BytesMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesMixedAfterCallback() {
+  free(returnStruct8BytesMixedResult.addressOf);
+
+  final result = returnStruct8BytesMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct8BytesMixedResult.addressOf);
+}
+
+typedef ReturnStruct9BytesIntType = Struct9BytesInt Function(Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesInt_a0 = 0;
+int returnStruct9BytesInt_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct9BytesInt returnStruct9BytesIntResult = Struct9BytesInt();
+
+Struct9BytesInt returnStruct9BytesIntCalculateResult() {
+  Struct9BytesInt result = allocate<Struct9BytesInt>().ref;
+
+  result.a0 = returnStruct9BytesInt_a0;
+  result.a1 = returnStruct9BytesInt_a1;
+
+  returnStruct9BytesIntResult = result;
+
+  return result;
+}
+
+/// Return value in two integer registers on x64.
+/// The second register only contains a single byte.
+Struct9BytesInt returnStruct9BytesInt(int a0, int a1) {
+  print("returnStruct9BytesInt(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct9BytesInt throwing on purpuse!");
+  }
+
+  returnStruct9BytesInt_a0 = a0;
+  returnStruct9BytesInt_a1 = a1;
+
+  final result = returnStruct9BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesIntAfterCallback() {
+  free(returnStruct9BytesIntResult.addressOf);
+
+  final result = returnStruct9BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct9BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct9BytesHomogeneousUint82Type = Struct9BytesHomogeneousUint82
+    Function(Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesHomogeneousUint82_a0 = 0;
+int returnStruct9BytesHomogeneousUint82_a1 = 0;
+int returnStruct9BytesHomogeneousUint82_a2 = 0;
+int returnStruct9BytesHomogeneousUint82_a3 = 0;
+int returnStruct9BytesHomogeneousUint82_a4 = 0;
+int returnStruct9BytesHomogeneousUint82_a5 = 0;
+int returnStruct9BytesHomogeneousUint82_a6 = 0;
+int returnStruct9BytesHomogeneousUint82_a7 = 0;
+int returnStruct9BytesHomogeneousUint82_a8 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82Result =
+    Struct9BytesHomogeneousUint82();
+
+Struct9BytesHomogeneousUint82
+    returnStruct9BytesHomogeneousUint82CalculateResult() {
+  Struct9BytesHomogeneousUint82 result =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+
+  result.a0 = returnStruct9BytesHomogeneousUint82_a0;
+  result.a1 = returnStruct9BytesHomogeneousUint82_a1;
+  result.a2 = returnStruct9BytesHomogeneousUint82_a2;
+  result.a3 = returnStruct9BytesHomogeneousUint82_a3;
+  result.a4 = returnStruct9BytesHomogeneousUint82_a4;
+  result.a5 = returnStruct9BytesHomogeneousUint82_a5;
+  result.a6 = returnStruct9BytesHomogeneousUint82_a6;
+  result.a7 = returnStruct9BytesHomogeneousUint82_a7;
+  result.a8 = returnStruct9BytesHomogeneousUint82_a8;
+
+  returnStruct9BytesHomogeneousUint82Result = result;
+
+  return result;
+}
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82(
+    int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
+  print(
+      "returnStruct9BytesHomogeneousUint82(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct9BytesHomogeneousUint82 throwing on purpuse!");
+  }
+
+  returnStruct9BytesHomogeneousUint82_a0 = a0;
+  returnStruct9BytesHomogeneousUint82_a1 = a1;
+  returnStruct9BytesHomogeneousUint82_a2 = a2;
+  returnStruct9BytesHomogeneousUint82_a3 = a3;
+  returnStruct9BytesHomogeneousUint82_a4 = a4;
+  returnStruct9BytesHomogeneousUint82_a5 = a5;
+  returnStruct9BytesHomogeneousUint82_a6 = a6;
+  returnStruct9BytesHomogeneousUint82_a7 = a7;
+  returnStruct9BytesHomogeneousUint82_a8 = a8;
+
+  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesHomogeneousUint82AfterCallback() {
+  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+
+  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+}
+
+typedef ReturnStruct12BytesHomogeneousFloatType = Struct12BytesHomogeneousFloat
+    Function(Float, Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct12BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct12BytesHomogeneousFloat_a1 = 0.0;
+double returnStruct12BytesHomogeneousFloat_a2 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct12BytesHomogeneousFloat returnStruct12BytesHomogeneousFloatResult =
+    Struct12BytesHomogeneousFloat();
+
+Struct12BytesHomogeneousFloat
+    returnStruct12BytesHomogeneousFloatCalculateResult() {
+  Struct12BytesHomogeneousFloat result =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct12BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct12BytesHomogeneousFloat_a1;
+  result.a2 = returnStruct12BytesHomogeneousFloat_a2;
+
+  returnStruct12BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value in FPU registers, but does not use all registers on arm hardfp
+/// and arm64.
+Struct12BytesHomogeneousFloat returnStruct12BytesHomogeneousFloat(
+    double a0, double a1, double a2) {
+  print("returnStruct12BytesHomogeneousFloat(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct12BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct12BytesHomogeneousFloat_a0 = a0;
+  returnStruct12BytesHomogeneousFloat_a1 = a1;
+  returnStruct12BytesHomogeneousFloat_a2 = a2;
+
+  final result = returnStruct12BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct12BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct12BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct16BytesHomogeneousFloatType = Struct16BytesHomogeneousFloat
+    Function(Float, Float, Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct16BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct16BytesHomogeneousFloat_a1 = 0.0;
+double returnStruct16BytesHomogeneousFloat_a2 = 0.0;
+double returnStruct16BytesHomogeneousFloat_a3 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct16BytesHomogeneousFloat returnStruct16BytesHomogeneousFloatResult =
+    Struct16BytesHomogeneousFloat();
+
+Struct16BytesHomogeneousFloat
+    returnStruct16BytesHomogeneousFloatCalculateResult() {
+  Struct16BytesHomogeneousFloat result =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct16BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct16BytesHomogeneousFloat_a1;
+  result.a2 = returnStruct16BytesHomogeneousFloat_a2;
+  result.a3 = returnStruct16BytesHomogeneousFloat_a3;
+
+  returnStruct16BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value in FPU registers on arm hardfp and arm64.
+Struct16BytesHomogeneousFloat returnStruct16BytesHomogeneousFloat(
+    double a0, double a1, double a2, double a3) {
+  print("returnStruct16BytesHomogeneousFloat(${a0}, ${a1}, ${a2}, ${a3})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct16BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct16BytesHomogeneousFloat_a0 = a0;
+  returnStruct16BytesHomogeneousFloat_a1 = a1;
+  returnStruct16BytesHomogeneousFloat_a2 = a2;
+  returnStruct16BytesHomogeneousFloat_a3 = a3;
+
+  final result = returnStruct16BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct16BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct16BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct16BytesMixedType = Struct16BytesMixed Function(
+    Double, Int64);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct16BytesMixed_a0 = 0.0;
+int returnStruct16BytesMixed_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct16BytesMixed returnStruct16BytesMixedResult = Struct16BytesMixed();
+
+Struct16BytesMixed returnStruct16BytesMixedCalculateResult() {
+  Struct16BytesMixed result = allocate<Struct16BytesMixed>().ref;
+
+  result.a0 = returnStruct16BytesMixed_a0;
+  result.a1 = returnStruct16BytesMixed_a1;
+
+  returnStruct16BytesMixedResult = result;
+
+  return result;
+}
+
+/// Return value split over FP and integer register in x64.
+Struct16BytesMixed returnStruct16BytesMixed(double a0, int a1) {
+  print("returnStruct16BytesMixed(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct16BytesMixed throwing on purpuse!");
+  }
+
+  returnStruct16BytesMixed_a0 = a0;
+  returnStruct16BytesMixed_a1 = a1;
+
+  final result = returnStruct16BytesMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct16BytesMixedAfterCallback() {
+  free(returnStruct16BytesMixedResult.addressOf);
+
+  final result = returnStruct16BytesMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct16BytesMixedResult.addressOf);
+}
+
+typedef ReturnStruct16BytesMixed2Type = Struct16BytesMixed2 Function(
+    Float, Float, Float, Int32);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct16BytesMixed2_a0 = 0.0;
+double returnStruct16BytesMixed2_a1 = 0.0;
+double returnStruct16BytesMixed2_a2 = 0.0;
+int returnStruct16BytesMixed2_a3 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct16BytesMixed2 returnStruct16BytesMixed2Result = Struct16BytesMixed2();
+
+Struct16BytesMixed2 returnStruct16BytesMixed2CalculateResult() {
+  Struct16BytesMixed2 result = allocate<Struct16BytesMixed2>().ref;
+
+  result.a0 = returnStruct16BytesMixed2_a0;
+  result.a1 = returnStruct16BytesMixed2_a1;
+  result.a2 = returnStruct16BytesMixed2_a2;
+  result.a3 = returnStruct16BytesMixed2_a3;
+
+  returnStruct16BytesMixed2Result = result;
+
+  return result;
+}
+
+/// Return value split over FP and integer register in x64.
+/// The integer register contains half float half int.
+Struct16BytesMixed2 returnStruct16BytesMixed2(
+    double a0, double a1, double a2, int a3) {
+  print("returnStruct16BytesMixed2(${a0}, ${a1}, ${a2}, ${a3})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct16BytesMixed2 throwing on purpuse!");
+  }
+
+  returnStruct16BytesMixed2_a0 = a0;
+  returnStruct16BytesMixed2_a1 = a1;
+  returnStruct16BytesMixed2_a2 = a2;
+  returnStruct16BytesMixed2_a3 = a3;
+
+  final result = returnStruct16BytesMixed2CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct16BytesMixed2AfterCallback() {
+  free(returnStruct16BytesMixed2Result.addressOf);
+
+  final result = returnStruct16BytesMixed2CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct16BytesMixed2Result.addressOf);
+}
+
+typedef ReturnStruct17BytesIntType = Struct17BytesInt Function(
+    Int64, Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct17BytesInt_a0 = 0;
+int returnStruct17BytesInt_a1 = 0;
+int returnStruct17BytesInt_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct17BytesInt returnStruct17BytesIntResult = Struct17BytesInt();
+
+Struct17BytesInt returnStruct17BytesIntCalculateResult() {
+  Struct17BytesInt result = allocate<Struct17BytesInt>().ref;
+
+  result.a0 = returnStruct17BytesInt_a0;
+  result.a1 = returnStruct17BytesInt_a1;
+  result.a2 = returnStruct17BytesInt_a2;
+
+  returnStruct17BytesIntResult = result;
+
+  return result;
+}
+
+/// Rerturn value returned in preallocated space passed by pointer on most ABIs.
+/// Is non word size on purpose, to test that structs are rounded up to word size
+/// on all ABIs.
+Struct17BytesInt returnStruct17BytesInt(int a0, int a1, int a2) {
+  print("returnStruct17BytesInt(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct17BytesInt throwing on purpuse!");
+  }
+
+  returnStruct17BytesInt_a0 = a0;
+  returnStruct17BytesInt_a1 = a1;
+  returnStruct17BytesInt_a2 = a2;
+
+  final result = returnStruct17BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct17BytesIntAfterCallback() {
+  free(returnStruct17BytesIntResult.addressOf);
+
+  final result = returnStruct17BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct17BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct19BytesHomogeneousUint8Type
+    = Struct19BytesHomogeneousUint8 Function(
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct19BytesHomogeneousUint8_a0 = 0;
+int returnStruct19BytesHomogeneousUint8_a1 = 0;
+int returnStruct19BytesHomogeneousUint8_a2 = 0;
+int returnStruct19BytesHomogeneousUint8_a3 = 0;
+int returnStruct19BytesHomogeneousUint8_a4 = 0;
+int returnStruct19BytesHomogeneousUint8_a5 = 0;
+int returnStruct19BytesHomogeneousUint8_a6 = 0;
+int returnStruct19BytesHomogeneousUint8_a7 = 0;
+int returnStruct19BytesHomogeneousUint8_a8 = 0;
+int returnStruct19BytesHomogeneousUint8_a9 = 0;
+int returnStruct19BytesHomogeneousUint8_a10 = 0;
+int returnStruct19BytesHomogeneousUint8_a11 = 0;
+int returnStruct19BytesHomogeneousUint8_a12 = 0;
+int returnStruct19BytesHomogeneousUint8_a13 = 0;
+int returnStruct19BytesHomogeneousUint8_a14 = 0;
+int returnStruct19BytesHomogeneousUint8_a15 = 0;
+int returnStruct19BytesHomogeneousUint8_a16 = 0;
+int returnStruct19BytesHomogeneousUint8_a17 = 0;
+int returnStruct19BytesHomogeneousUint8_a18 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct19BytesHomogeneousUint8 returnStruct19BytesHomogeneousUint8Result =
+    Struct19BytesHomogeneousUint8();
+
+Struct19BytesHomogeneousUint8
+    returnStruct19BytesHomogeneousUint8CalculateResult() {
+  Struct19BytesHomogeneousUint8 result =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+
+  result.a0 = returnStruct19BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct19BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct19BytesHomogeneousUint8_a2;
+  result.a3 = returnStruct19BytesHomogeneousUint8_a3;
+  result.a4 = returnStruct19BytesHomogeneousUint8_a4;
+  result.a5 = returnStruct19BytesHomogeneousUint8_a5;
+  result.a6 = returnStruct19BytesHomogeneousUint8_a6;
+  result.a7 = returnStruct19BytesHomogeneousUint8_a7;
+  result.a8 = returnStruct19BytesHomogeneousUint8_a8;
+  result.a9 = returnStruct19BytesHomogeneousUint8_a9;
+  result.a10 = returnStruct19BytesHomogeneousUint8_a10;
+  result.a11 = returnStruct19BytesHomogeneousUint8_a11;
+  result.a12 = returnStruct19BytesHomogeneousUint8_a12;
+  result.a13 = returnStruct19BytesHomogeneousUint8_a13;
+  result.a14 = returnStruct19BytesHomogeneousUint8_a14;
+  result.a15 = returnStruct19BytesHomogeneousUint8_a15;
+  result.a16 = returnStruct19BytesHomogeneousUint8_a16;
+  result.a17 = returnStruct19BytesHomogeneousUint8_a17;
+  result.a18 = returnStruct19BytesHomogeneousUint8_a18;
+
+  returnStruct19BytesHomogeneousUint8Result = result;
+
+  return result;
+}
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+Struct19BytesHomogeneousUint8 returnStruct19BytesHomogeneousUint8(
+    int a0,
+    int a1,
+    int a2,
+    int a3,
+    int a4,
+    int a5,
+    int a6,
+    int a7,
+    int a8,
+    int a9,
+    int a10,
+    int a11,
+    int a12,
+    int a13,
+    int a14,
+    int a15,
+    int a16,
+    int a17,
+    int a18) {
+  print(
+      "returnStruct19BytesHomogeneousUint8(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct19BytesHomogeneousUint8 throwing on purpuse!");
+  }
+
+  returnStruct19BytesHomogeneousUint8_a0 = a0;
+  returnStruct19BytesHomogeneousUint8_a1 = a1;
+  returnStruct19BytesHomogeneousUint8_a2 = a2;
+  returnStruct19BytesHomogeneousUint8_a3 = a3;
+  returnStruct19BytesHomogeneousUint8_a4 = a4;
+  returnStruct19BytesHomogeneousUint8_a5 = a5;
+  returnStruct19BytesHomogeneousUint8_a6 = a6;
+  returnStruct19BytesHomogeneousUint8_a7 = a7;
+  returnStruct19BytesHomogeneousUint8_a8 = a8;
+  returnStruct19BytesHomogeneousUint8_a9 = a9;
+  returnStruct19BytesHomogeneousUint8_a10 = a10;
+  returnStruct19BytesHomogeneousUint8_a11 = a11;
+  returnStruct19BytesHomogeneousUint8_a12 = a12;
+  returnStruct19BytesHomogeneousUint8_a13 = a13;
+  returnStruct19BytesHomogeneousUint8_a14 = a14;
+  returnStruct19BytesHomogeneousUint8_a15 = a15;
+  returnStruct19BytesHomogeneousUint8_a16 = a16;
+  returnStruct19BytesHomogeneousUint8_a17 = a17;
+  returnStruct19BytesHomogeneousUint8_a18 = a18;
+
+  final result = returnStruct19BytesHomogeneousUint8CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct19BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+
+  final result = returnStruct19BytesHomogeneousUint8CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct20BytesHomogeneousInt32Type = Struct20BytesHomogeneousInt32
+    Function(Int32, Int32, Int32, Int32, Int32);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct20BytesHomogeneousInt32_a0 = 0;
+int returnStruct20BytesHomogeneousInt32_a1 = 0;
+int returnStruct20BytesHomogeneousInt32_a2 = 0;
+int returnStruct20BytesHomogeneousInt32_a3 = 0;
+int returnStruct20BytesHomogeneousInt32_a4 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousInt32 returnStruct20BytesHomogeneousInt32Result =
+    Struct20BytesHomogeneousInt32();
+
+Struct20BytesHomogeneousInt32
+    returnStruct20BytesHomogeneousInt32CalculateResult() {
+  Struct20BytesHomogeneousInt32 result =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  result.a0 = returnStruct20BytesHomogeneousInt32_a0;
+  result.a1 = returnStruct20BytesHomogeneousInt32_a1;
+  result.a2 = returnStruct20BytesHomogeneousInt32_a2;
+  result.a3 = returnStruct20BytesHomogeneousInt32_a3;
+  result.a4 = returnStruct20BytesHomogeneousInt32_a4;
+
+  returnStruct20BytesHomogeneousInt32Result = result;
+
+  return result;
+}
+
+/// Return value too big to go in cpu registers on arm64.
+Struct20BytesHomogeneousInt32 returnStruct20BytesHomogeneousInt32(
+    int a0, int a1, int a2, int a3, int a4) {
+  print(
+      "returnStruct20BytesHomogeneousInt32(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct20BytesHomogeneousInt32 throwing on purpuse!");
+  }
+
+  returnStruct20BytesHomogeneousInt32_a0 = a0;
+  returnStruct20BytesHomogeneousInt32_a1 = a1;
+  returnStruct20BytesHomogeneousInt32_a2 = a2;
+  returnStruct20BytesHomogeneousInt32_a3 = a3;
+  returnStruct20BytesHomogeneousInt32_a4 = a4;
+
+  final result = returnStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct20BytesHomogeneousInt32AfterCallback() {
+  free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+
+  final result = returnStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+}
+
+typedef ReturnStruct20BytesHomogeneousFloatType = Struct20BytesHomogeneousFloat
+    Function(Float, Float, Float, Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct20BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a1 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a2 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a3 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a4 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousFloat returnStruct20BytesHomogeneousFloatResult =
+    Struct20BytesHomogeneousFloat();
+
+Struct20BytesHomogeneousFloat
+    returnStruct20BytesHomogeneousFloatCalculateResult() {
+  Struct20BytesHomogeneousFloat result =
+      allocate<Struct20BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct20BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct20BytesHomogeneousFloat_a1;
+  result.a2 = returnStruct20BytesHomogeneousFloat_a2;
+  result.a3 = returnStruct20BytesHomogeneousFloat_a3;
+  result.a4 = returnStruct20BytesHomogeneousFloat_a4;
+
+  returnStruct20BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
+Struct20BytesHomogeneousFloat returnStruct20BytesHomogeneousFloat(
+    double a0, double a1, double a2, double a3, double a4) {
+  print(
+      "returnStruct20BytesHomogeneousFloat(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct20BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct20BytesHomogeneousFloat_a0 = a0;
+  returnStruct20BytesHomogeneousFloat_a1 = a1;
+  returnStruct20BytesHomogeneousFloat_a2 = a2;
+  returnStruct20BytesHomogeneousFloat_a3 = a3;
+  returnStruct20BytesHomogeneousFloat_a4 = a4;
+
+  final result = returnStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct20BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct32BytesHomogeneousDoubleType
+    = Struct32BytesHomogeneousDouble Function(Double, Double, Double, Double);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct32BytesHomogeneousDouble_a0 = 0.0;
+double returnStruct32BytesHomogeneousDouble_a1 = 0.0;
+double returnStruct32BytesHomogeneousDouble_a2 = 0.0;
+double returnStruct32BytesHomogeneousDouble_a3 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct32BytesHomogeneousDouble returnStruct32BytesHomogeneousDoubleResult =
+    Struct32BytesHomogeneousDouble();
+
+Struct32BytesHomogeneousDouble
+    returnStruct32BytesHomogeneousDoubleCalculateResult() {
+  Struct32BytesHomogeneousDouble result =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+
+  result.a0 = returnStruct32BytesHomogeneousDouble_a0;
+  result.a1 = returnStruct32BytesHomogeneousDouble_a1;
+  result.a2 = returnStruct32BytesHomogeneousDouble_a2;
+  result.a3 = returnStruct32BytesHomogeneousDouble_a3;
+
+  returnStruct32BytesHomogeneousDoubleResult = result;
+
+  return result;
+}
+
+/// Return value in FPU registers on arm64.
+Struct32BytesHomogeneousDouble returnStruct32BytesHomogeneousDouble(
+    double a0, double a1, double a2, double a3) {
+  print("returnStruct32BytesHomogeneousDouble(${a0}, ${a1}, ${a2}, ${a3})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct32BytesHomogeneousDouble throwing on purpuse!");
+  }
+
+  returnStruct32BytesHomogeneousDouble_a0 = a0;
+  returnStruct32BytesHomogeneousDouble_a1 = a1;
+  returnStruct32BytesHomogeneousDouble_a2 = a2;
+  returnStruct32BytesHomogeneousDouble_a3 = a3;
+
+  final result = returnStruct32BytesHomogeneousDoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct32BytesHomogeneousDoubleAfterCallback() {
+  free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+
+  final result = returnStruct32BytesHomogeneousDoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+}
+
+typedef ReturnStruct40BytesHomogeneousDoubleType
+    = Struct40BytesHomogeneousDouble Function(
+        Double, Double, Double, Double, Double);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct40BytesHomogeneousDouble_a0 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a1 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a2 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a3 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a4 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct40BytesHomogeneousDouble returnStruct40BytesHomogeneousDoubleResult =
+    Struct40BytesHomogeneousDouble();
+
+Struct40BytesHomogeneousDouble
+    returnStruct40BytesHomogeneousDoubleCalculateResult() {
+  Struct40BytesHomogeneousDouble result =
+      allocate<Struct40BytesHomogeneousDouble>().ref;
+
+  result.a0 = returnStruct40BytesHomogeneousDouble_a0;
+  result.a1 = returnStruct40BytesHomogeneousDouble_a1;
+  result.a2 = returnStruct40BytesHomogeneousDouble_a2;
+  result.a3 = returnStruct40BytesHomogeneousDouble_a3;
+  result.a4 = returnStruct40BytesHomogeneousDouble_a4;
+
+  returnStruct40BytesHomogeneousDoubleResult = result;
+
+  return result;
+}
+
+/// Return value too big to go in FPU registers on arm64.
+Struct40BytesHomogeneousDouble returnStruct40BytesHomogeneousDouble(
+    double a0, double a1, double a2, double a3, double a4) {
+  print(
+      "returnStruct40BytesHomogeneousDouble(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct40BytesHomogeneousDouble throwing on purpuse!");
+  }
+
+  returnStruct40BytesHomogeneousDouble_a0 = a0;
+  returnStruct40BytesHomogeneousDouble_a1 = a1;
+  returnStruct40BytesHomogeneousDouble_a2 = a2;
+  returnStruct40BytesHomogeneousDouble_a3 = a3;
+  returnStruct40BytesHomogeneousDouble_a4 = a4;
+
+  final result = returnStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct40BytesHomogeneousDoubleAfterCallback() {
+  free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+
+  final result = returnStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+}
+
+typedef ReturnStruct1024BytesHomogeneousUint64Type
+    = Struct1024BytesHomogeneousUint64 Function(
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct1024BytesHomogeneousUint64_a0 = 0;
+int returnStruct1024BytesHomogeneousUint64_a1 = 0;
+int returnStruct1024BytesHomogeneousUint64_a2 = 0;
+int returnStruct1024BytesHomogeneousUint64_a3 = 0;
+int returnStruct1024BytesHomogeneousUint64_a4 = 0;
+int returnStruct1024BytesHomogeneousUint64_a5 = 0;
+int returnStruct1024BytesHomogeneousUint64_a6 = 0;
+int returnStruct1024BytesHomogeneousUint64_a7 = 0;
+int returnStruct1024BytesHomogeneousUint64_a8 = 0;
+int returnStruct1024BytesHomogeneousUint64_a9 = 0;
+int returnStruct1024BytesHomogeneousUint64_a10 = 0;
+int returnStruct1024BytesHomogeneousUint64_a11 = 0;
+int returnStruct1024BytesHomogeneousUint64_a12 = 0;
+int returnStruct1024BytesHomogeneousUint64_a13 = 0;
+int returnStruct1024BytesHomogeneousUint64_a14 = 0;
+int returnStruct1024BytesHomogeneousUint64_a15 = 0;
+int returnStruct1024BytesHomogeneousUint64_a16 = 0;
+int returnStruct1024BytesHomogeneousUint64_a17 = 0;
+int returnStruct1024BytesHomogeneousUint64_a18 = 0;
+int returnStruct1024BytesHomogeneousUint64_a19 = 0;
+int returnStruct1024BytesHomogeneousUint64_a20 = 0;
+int returnStruct1024BytesHomogeneousUint64_a21 = 0;
+int returnStruct1024BytesHomogeneousUint64_a22 = 0;
+int returnStruct1024BytesHomogeneousUint64_a23 = 0;
+int returnStruct1024BytesHomogeneousUint64_a24 = 0;
+int returnStruct1024BytesHomogeneousUint64_a25 = 0;
+int returnStruct1024BytesHomogeneousUint64_a26 = 0;
+int returnStruct1024BytesHomogeneousUint64_a27 = 0;
+int returnStruct1024BytesHomogeneousUint64_a28 = 0;
+int returnStruct1024BytesHomogeneousUint64_a29 = 0;
+int returnStruct1024BytesHomogeneousUint64_a30 = 0;
+int returnStruct1024BytesHomogeneousUint64_a31 = 0;
+int returnStruct1024BytesHomogeneousUint64_a32 = 0;
+int returnStruct1024BytesHomogeneousUint64_a33 = 0;
+int returnStruct1024BytesHomogeneousUint64_a34 = 0;
+int returnStruct1024BytesHomogeneousUint64_a35 = 0;
+int returnStruct1024BytesHomogeneousUint64_a36 = 0;
+int returnStruct1024BytesHomogeneousUint64_a37 = 0;
+int returnStruct1024BytesHomogeneousUint64_a38 = 0;
+int returnStruct1024BytesHomogeneousUint64_a39 = 0;
+int returnStruct1024BytesHomogeneousUint64_a40 = 0;
+int returnStruct1024BytesHomogeneousUint64_a41 = 0;
+int returnStruct1024BytesHomogeneousUint64_a42 = 0;
+int returnStruct1024BytesHomogeneousUint64_a43 = 0;
+int returnStruct1024BytesHomogeneousUint64_a44 = 0;
+int returnStruct1024BytesHomogeneousUint64_a45 = 0;
+int returnStruct1024BytesHomogeneousUint64_a46 = 0;
+int returnStruct1024BytesHomogeneousUint64_a47 = 0;
+int returnStruct1024BytesHomogeneousUint64_a48 = 0;
+int returnStruct1024BytesHomogeneousUint64_a49 = 0;
+int returnStruct1024BytesHomogeneousUint64_a50 = 0;
+int returnStruct1024BytesHomogeneousUint64_a51 = 0;
+int returnStruct1024BytesHomogeneousUint64_a52 = 0;
+int returnStruct1024BytesHomogeneousUint64_a53 = 0;
+int returnStruct1024BytesHomogeneousUint64_a54 = 0;
+int returnStruct1024BytesHomogeneousUint64_a55 = 0;
+int returnStruct1024BytesHomogeneousUint64_a56 = 0;
+int returnStruct1024BytesHomogeneousUint64_a57 = 0;
+int returnStruct1024BytesHomogeneousUint64_a58 = 0;
+int returnStruct1024BytesHomogeneousUint64_a59 = 0;
+int returnStruct1024BytesHomogeneousUint64_a60 = 0;
+int returnStruct1024BytesHomogeneousUint64_a61 = 0;
+int returnStruct1024BytesHomogeneousUint64_a62 = 0;
+int returnStruct1024BytesHomogeneousUint64_a63 = 0;
+int returnStruct1024BytesHomogeneousUint64_a64 = 0;
+int returnStruct1024BytesHomogeneousUint64_a65 = 0;
+int returnStruct1024BytesHomogeneousUint64_a66 = 0;
+int returnStruct1024BytesHomogeneousUint64_a67 = 0;
+int returnStruct1024BytesHomogeneousUint64_a68 = 0;
+int returnStruct1024BytesHomogeneousUint64_a69 = 0;
+int returnStruct1024BytesHomogeneousUint64_a70 = 0;
+int returnStruct1024BytesHomogeneousUint64_a71 = 0;
+int returnStruct1024BytesHomogeneousUint64_a72 = 0;
+int returnStruct1024BytesHomogeneousUint64_a73 = 0;
+int returnStruct1024BytesHomogeneousUint64_a74 = 0;
+int returnStruct1024BytesHomogeneousUint64_a75 = 0;
+int returnStruct1024BytesHomogeneousUint64_a76 = 0;
+int returnStruct1024BytesHomogeneousUint64_a77 = 0;
+int returnStruct1024BytesHomogeneousUint64_a78 = 0;
+int returnStruct1024BytesHomogeneousUint64_a79 = 0;
+int returnStruct1024BytesHomogeneousUint64_a80 = 0;
+int returnStruct1024BytesHomogeneousUint64_a81 = 0;
+int returnStruct1024BytesHomogeneousUint64_a82 = 0;
+int returnStruct1024BytesHomogeneousUint64_a83 = 0;
+int returnStruct1024BytesHomogeneousUint64_a84 = 0;
+int returnStruct1024BytesHomogeneousUint64_a85 = 0;
+int returnStruct1024BytesHomogeneousUint64_a86 = 0;
+int returnStruct1024BytesHomogeneousUint64_a87 = 0;
+int returnStruct1024BytesHomogeneousUint64_a88 = 0;
+int returnStruct1024BytesHomogeneousUint64_a89 = 0;
+int returnStruct1024BytesHomogeneousUint64_a90 = 0;
+int returnStruct1024BytesHomogeneousUint64_a91 = 0;
+int returnStruct1024BytesHomogeneousUint64_a92 = 0;
+int returnStruct1024BytesHomogeneousUint64_a93 = 0;
+int returnStruct1024BytesHomogeneousUint64_a94 = 0;
+int returnStruct1024BytesHomogeneousUint64_a95 = 0;
+int returnStruct1024BytesHomogeneousUint64_a96 = 0;
+int returnStruct1024BytesHomogeneousUint64_a97 = 0;
+int returnStruct1024BytesHomogeneousUint64_a98 = 0;
+int returnStruct1024BytesHomogeneousUint64_a99 = 0;
+int returnStruct1024BytesHomogeneousUint64_a100 = 0;
+int returnStruct1024BytesHomogeneousUint64_a101 = 0;
+int returnStruct1024BytesHomogeneousUint64_a102 = 0;
+int returnStruct1024BytesHomogeneousUint64_a103 = 0;
+int returnStruct1024BytesHomogeneousUint64_a104 = 0;
+int returnStruct1024BytesHomogeneousUint64_a105 = 0;
+int returnStruct1024BytesHomogeneousUint64_a106 = 0;
+int returnStruct1024BytesHomogeneousUint64_a107 = 0;
+int returnStruct1024BytesHomogeneousUint64_a108 = 0;
+int returnStruct1024BytesHomogeneousUint64_a109 = 0;
+int returnStruct1024BytesHomogeneousUint64_a110 = 0;
+int returnStruct1024BytesHomogeneousUint64_a111 = 0;
+int returnStruct1024BytesHomogeneousUint64_a112 = 0;
+int returnStruct1024BytesHomogeneousUint64_a113 = 0;
+int returnStruct1024BytesHomogeneousUint64_a114 = 0;
+int returnStruct1024BytesHomogeneousUint64_a115 = 0;
+int returnStruct1024BytesHomogeneousUint64_a116 = 0;
+int returnStruct1024BytesHomogeneousUint64_a117 = 0;
+int returnStruct1024BytesHomogeneousUint64_a118 = 0;
+int returnStruct1024BytesHomogeneousUint64_a119 = 0;
+int returnStruct1024BytesHomogeneousUint64_a120 = 0;
+int returnStruct1024BytesHomogeneousUint64_a121 = 0;
+int returnStruct1024BytesHomogeneousUint64_a122 = 0;
+int returnStruct1024BytesHomogeneousUint64_a123 = 0;
+int returnStruct1024BytesHomogeneousUint64_a124 = 0;
+int returnStruct1024BytesHomogeneousUint64_a125 = 0;
+int returnStruct1024BytesHomogeneousUint64_a126 = 0;
+int returnStruct1024BytesHomogeneousUint64_a127 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct1024BytesHomogeneousUint64 returnStruct1024BytesHomogeneousUint64Result =
+    Struct1024BytesHomogeneousUint64();
+
+Struct1024BytesHomogeneousUint64
+    returnStruct1024BytesHomogeneousUint64CalculateResult() {
+  Struct1024BytesHomogeneousUint64 result =
+      allocate<Struct1024BytesHomogeneousUint64>().ref;
+
+  result.a0 = returnStruct1024BytesHomogeneousUint64_a0;
+  result.a1 = returnStruct1024BytesHomogeneousUint64_a1;
+  result.a2 = returnStruct1024BytesHomogeneousUint64_a2;
+  result.a3 = returnStruct1024BytesHomogeneousUint64_a3;
+  result.a4 = returnStruct1024BytesHomogeneousUint64_a4;
+  result.a5 = returnStruct1024BytesHomogeneousUint64_a5;
+  result.a6 = returnStruct1024BytesHomogeneousUint64_a6;
+  result.a7 = returnStruct1024BytesHomogeneousUint64_a7;
+  result.a8 = returnStruct1024BytesHomogeneousUint64_a8;
+  result.a9 = returnStruct1024BytesHomogeneousUint64_a9;
+  result.a10 = returnStruct1024BytesHomogeneousUint64_a10;
+  result.a11 = returnStruct1024BytesHomogeneousUint64_a11;
+  result.a12 = returnStruct1024BytesHomogeneousUint64_a12;
+  result.a13 = returnStruct1024BytesHomogeneousUint64_a13;
+  result.a14 = returnStruct1024BytesHomogeneousUint64_a14;
+  result.a15 = returnStruct1024BytesHomogeneousUint64_a15;
+  result.a16 = returnStruct1024BytesHomogeneousUint64_a16;
+  result.a17 = returnStruct1024BytesHomogeneousUint64_a17;
+  result.a18 = returnStruct1024BytesHomogeneousUint64_a18;
+  result.a19 = returnStruct1024BytesHomogeneousUint64_a19;
+  result.a20 = returnStruct1024BytesHomogeneousUint64_a20;
+  result.a21 = returnStruct1024BytesHomogeneousUint64_a21;
+  result.a22 = returnStruct1024BytesHomogeneousUint64_a22;
+  result.a23 = returnStruct1024BytesHomogeneousUint64_a23;
+  result.a24 = returnStruct1024BytesHomogeneousUint64_a24;
+  result.a25 = returnStruct1024BytesHomogeneousUint64_a25;
+  result.a26 = returnStruct1024BytesHomogeneousUint64_a26;
+  result.a27 = returnStruct1024BytesHomogeneousUint64_a27;
+  result.a28 = returnStruct1024BytesHomogeneousUint64_a28;
+  result.a29 = returnStruct1024BytesHomogeneousUint64_a29;
+  result.a30 = returnStruct1024BytesHomogeneousUint64_a30;
+  result.a31 = returnStruct1024BytesHomogeneousUint64_a31;
+  result.a32 = returnStruct1024BytesHomogeneousUint64_a32;
+  result.a33 = returnStruct1024BytesHomogeneousUint64_a33;
+  result.a34 = returnStruct1024BytesHomogeneousUint64_a34;
+  result.a35 = returnStruct1024BytesHomogeneousUint64_a35;
+  result.a36 = returnStruct1024BytesHomogeneousUint64_a36;
+  result.a37 = returnStruct1024BytesHomogeneousUint64_a37;
+  result.a38 = returnStruct1024BytesHomogeneousUint64_a38;
+  result.a39 = returnStruct1024BytesHomogeneousUint64_a39;
+  result.a40 = returnStruct1024BytesHomogeneousUint64_a40;
+  result.a41 = returnStruct1024BytesHomogeneousUint64_a41;
+  result.a42 = returnStruct1024BytesHomogeneousUint64_a42;
+  result.a43 = returnStruct1024BytesHomogeneousUint64_a43;
+  result.a44 = returnStruct1024BytesHomogeneousUint64_a44;
+  result.a45 = returnStruct1024BytesHomogeneousUint64_a45;
+  result.a46 = returnStruct1024BytesHomogeneousUint64_a46;
+  result.a47 = returnStruct1024BytesHomogeneousUint64_a47;
+  result.a48 = returnStruct1024BytesHomogeneousUint64_a48;
+  result.a49 = returnStruct1024BytesHomogeneousUint64_a49;
+  result.a50 = returnStruct1024BytesHomogeneousUint64_a50;
+  result.a51 = returnStruct1024BytesHomogeneousUint64_a51;
+  result.a52 = returnStruct1024BytesHomogeneousUint64_a52;
+  result.a53 = returnStruct1024BytesHomogeneousUint64_a53;
+  result.a54 = returnStruct1024BytesHomogeneousUint64_a54;
+  result.a55 = returnStruct1024BytesHomogeneousUint64_a55;
+  result.a56 = returnStruct1024BytesHomogeneousUint64_a56;
+  result.a57 = returnStruct1024BytesHomogeneousUint64_a57;
+  result.a58 = returnStruct1024BytesHomogeneousUint64_a58;
+  result.a59 = returnStruct1024BytesHomogeneousUint64_a59;
+  result.a60 = returnStruct1024BytesHomogeneousUint64_a60;
+  result.a61 = returnStruct1024BytesHomogeneousUint64_a61;
+  result.a62 = returnStruct1024BytesHomogeneousUint64_a62;
+  result.a63 = returnStruct1024BytesHomogeneousUint64_a63;
+  result.a64 = returnStruct1024BytesHomogeneousUint64_a64;
+  result.a65 = returnStruct1024BytesHomogeneousUint64_a65;
+  result.a66 = returnStruct1024BytesHomogeneousUint64_a66;
+  result.a67 = returnStruct1024BytesHomogeneousUint64_a67;
+  result.a68 = returnStruct1024BytesHomogeneousUint64_a68;
+  result.a69 = returnStruct1024BytesHomogeneousUint64_a69;
+  result.a70 = returnStruct1024BytesHomogeneousUint64_a70;
+  result.a71 = returnStruct1024BytesHomogeneousUint64_a71;
+  result.a72 = returnStruct1024BytesHomogeneousUint64_a72;
+  result.a73 = returnStruct1024BytesHomogeneousUint64_a73;
+  result.a74 = returnStruct1024BytesHomogeneousUint64_a74;
+  result.a75 = returnStruct1024BytesHomogeneousUint64_a75;
+  result.a76 = returnStruct1024BytesHomogeneousUint64_a76;
+  result.a77 = returnStruct1024BytesHomogeneousUint64_a77;
+  result.a78 = returnStruct1024BytesHomogeneousUint64_a78;
+  result.a79 = returnStruct1024BytesHomogeneousUint64_a79;
+  result.a80 = returnStruct1024BytesHomogeneousUint64_a80;
+  result.a81 = returnStruct1024BytesHomogeneousUint64_a81;
+  result.a82 = returnStruct1024BytesHomogeneousUint64_a82;
+  result.a83 = returnStruct1024BytesHomogeneousUint64_a83;
+  result.a84 = returnStruct1024BytesHomogeneousUint64_a84;
+  result.a85 = returnStruct1024BytesHomogeneousUint64_a85;
+  result.a86 = returnStruct1024BytesHomogeneousUint64_a86;
+  result.a87 = returnStruct1024BytesHomogeneousUint64_a87;
+  result.a88 = returnStruct1024BytesHomogeneousUint64_a88;
+  result.a89 = returnStruct1024BytesHomogeneousUint64_a89;
+  result.a90 = returnStruct1024BytesHomogeneousUint64_a90;
+  result.a91 = returnStruct1024BytesHomogeneousUint64_a91;
+  result.a92 = returnStruct1024BytesHomogeneousUint64_a92;
+  result.a93 = returnStruct1024BytesHomogeneousUint64_a93;
+  result.a94 = returnStruct1024BytesHomogeneousUint64_a94;
+  result.a95 = returnStruct1024BytesHomogeneousUint64_a95;
+  result.a96 = returnStruct1024BytesHomogeneousUint64_a96;
+  result.a97 = returnStruct1024BytesHomogeneousUint64_a97;
+  result.a98 = returnStruct1024BytesHomogeneousUint64_a98;
+  result.a99 = returnStruct1024BytesHomogeneousUint64_a99;
+  result.a100 = returnStruct1024BytesHomogeneousUint64_a100;
+  result.a101 = returnStruct1024BytesHomogeneousUint64_a101;
+  result.a102 = returnStruct1024BytesHomogeneousUint64_a102;
+  result.a103 = returnStruct1024BytesHomogeneousUint64_a103;
+  result.a104 = returnStruct1024BytesHomogeneousUint64_a104;
+  result.a105 = returnStruct1024BytesHomogeneousUint64_a105;
+  result.a106 = returnStruct1024BytesHomogeneousUint64_a106;
+  result.a107 = returnStruct1024BytesHomogeneousUint64_a107;
+  result.a108 = returnStruct1024BytesHomogeneousUint64_a108;
+  result.a109 = returnStruct1024BytesHomogeneousUint64_a109;
+  result.a110 = returnStruct1024BytesHomogeneousUint64_a110;
+  result.a111 = returnStruct1024BytesHomogeneousUint64_a111;
+  result.a112 = returnStruct1024BytesHomogeneousUint64_a112;
+  result.a113 = returnStruct1024BytesHomogeneousUint64_a113;
+  result.a114 = returnStruct1024BytesHomogeneousUint64_a114;
+  result.a115 = returnStruct1024BytesHomogeneousUint64_a115;
+  result.a116 = returnStruct1024BytesHomogeneousUint64_a116;
+  result.a117 = returnStruct1024BytesHomogeneousUint64_a117;
+  result.a118 = returnStruct1024BytesHomogeneousUint64_a118;
+  result.a119 = returnStruct1024BytesHomogeneousUint64_a119;
+  result.a120 = returnStruct1024BytesHomogeneousUint64_a120;
+  result.a121 = returnStruct1024BytesHomogeneousUint64_a121;
+  result.a122 = returnStruct1024BytesHomogeneousUint64_a122;
+  result.a123 = returnStruct1024BytesHomogeneousUint64_a123;
+  result.a124 = returnStruct1024BytesHomogeneousUint64_a124;
+  result.a125 = returnStruct1024BytesHomogeneousUint64_a125;
+  result.a126 = returnStruct1024BytesHomogeneousUint64_a126;
+  result.a127 = returnStruct1024BytesHomogeneousUint64_a127;
+
+  returnStruct1024BytesHomogeneousUint64Result = result;
+
+  return result;
+}
+
+/// Test 1kb struct.
+Struct1024BytesHomogeneousUint64 returnStruct1024BytesHomogeneousUint64(
+    int a0,
+    int a1,
+    int a2,
+    int a3,
+    int a4,
+    int a5,
+    int a6,
+    int a7,
+    int a8,
+    int a9,
+    int a10,
+    int a11,
+    int a12,
+    int a13,
+    int a14,
+    int a15,
+    int a16,
+    int a17,
+    int a18,
+    int a19,
+    int a20,
+    int a21,
+    int a22,
+    int a23,
+    int a24,
+    int a25,
+    int a26,
+    int a27,
+    int a28,
+    int a29,
+    int a30,
+    int a31,
+    int a32,
+    int a33,
+    int a34,
+    int a35,
+    int a36,
+    int a37,
+    int a38,
+    int a39,
+    int a40,
+    int a41,
+    int a42,
+    int a43,
+    int a44,
+    int a45,
+    int a46,
+    int a47,
+    int a48,
+    int a49,
+    int a50,
+    int a51,
+    int a52,
+    int a53,
+    int a54,
+    int a55,
+    int a56,
+    int a57,
+    int a58,
+    int a59,
+    int a60,
+    int a61,
+    int a62,
+    int a63,
+    int a64,
+    int a65,
+    int a66,
+    int a67,
+    int a68,
+    int a69,
+    int a70,
+    int a71,
+    int a72,
+    int a73,
+    int a74,
+    int a75,
+    int a76,
+    int a77,
+    int a78,
+    int a79,
+    int a80,
+    int a81,
+    int a82,
+    int a83,
+    int a84,
+    int a85,
+    int a86,
+    int a87,
+    int a88,
+    int a89,
+    int a90,
+    int a91,
+    int a92,
+    int a93,
+    int a94,
+    int a95,
+    int a96,
+    int a97,
+    int a98,
+    int a99,
+    int a100,
+    int a101,
+    int a102,
+    int a103,
+    int a104,
+    int a105,
+    int a106,
+    int a107,
+    int a108,
+    int a109,
+    int a110,
+    int a111,
+    int a112,
+    int a113,
+    int a114,
+    int a115,
+    int a116,
+    int a117,
+    int a118,
+    int a119,
+    int a120,
+    int a121,
+    int a122,
+    int a123,
+    int a124,
+    int a125,
+    int a126,
+    int a127) {
+  print(
+      "returnStruct1024BytesHomogeneousUint64(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18}, ${a19}, ${a20}, ${a21}, ${a22}, ${a23}, ${a24}, ${a25}, ${a26}, ${a27}, ${a28}, ${a29}, ${a30}, ${a31}, ${a32}, ${a33}, ${a34}, ${a35}, ${a36}, ${a37}, ${a38}, ${a39}, ${a40}, ${a41}, ${a42}, ${a43}, ${a44}, ${a45}, ${a46}, ${a47}, ${a48}, ${a49}, ${a50}, ${a51}, ${a52}, ${a53}, ${a54}, ${a55}, ${a56}, ${a57}, ${a58}, ${a59}, ${a60}, ${a61}, ${a62}, ${a63}, ${a64}, ${a65}, ${a66}, ${a67}, ${a68}, ${a69}, ${a70}, ${a71}, ${a72}, ${a73}, ${a74}, ${a75}, ${a76}, ${a77}, ${a78}, ${a79}, ${a80}, ${a81}, ${a82}, ${a83}, ${a84}, ${a85}, ${a86}, ${a87}, ${a88}, ${a89}, ${a90}, ${a91}, ${a92}, ${a93}, ${a94}, ${a95}, ${a96}, ${a97}, ${a98}, ${a99}, ${a100}, ${a101}, ${a102}, ${a103}, ${a104}, ${a105}, ${a106}, ${a107}, ${a108}, ${a109}, ${a110}, ${a111}, ${a112}, ${a113}, ${a114}, ${a115}, ${a116}, ${a117}, ${a118}, ${a119}, ${a120}, ${a121}, ${a122}, ${a123}, ${a124}, ${a125}, ${a126}, ${a127})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct1024BytesHomogeneousUint64 throwing on purpuse!");
+  }
+
+  returnStruct1024BytesHomogeneousUint64_a0 = a0;
+  returnStruct1024BytesHomogeneousUint64_a1 = a1;
+  returnStruct1024BytesHomogeneousUint64_a2 = a2;
+  returnStruct1024BytesHomogeneousUint64_a3 = a3;
+  returnStruct1024BytesHomogeneousUint64_a4 = a4;
+  returnStruct1024BytesHomogeneousUint64_a5 = a5;
+  returnStruct1024BytesHomogeneousUint64_a6 = a6;
+  returnStruct1024BytesHomogeneousUint64_a7 = a7;
+  returnStruct1024BytesHomogeneousUint64_a8 = a8;
+  returnStruct1024BytesHomogeneousUint64_a9 = a9;
+  returnStruct1024BytesHomogeneousUint64_a10 = a10;
+  returnStruct1024BytesHomogeneousUint64_a11 = a11;
+  returnStruct1024BytesHomogeneousUint64_a12 = a12;
+  returnStruct1024BytesHomogeneousUint64_a13 = a13;
+  returnStruct1024BytesHomogeneousUint64_a14 = a14;
+  returnStruct1024BytesHomogeneousUint64_a15 = a15;
+  returnStruct1024BytesHomogeneousUint64_a16 = a16;
+  returnStruct1024BytesHomogeneousUint64_a17 = a17;
+  returnStruct1024BytesHomogeneousUint64_a18 = a18;
+  returnStruct1024BytesHomogeneousUint64_a19 = a19;
+  returnStruct1024BytesHomogeneousUint64_a20 = a20;
+  returnStruct1024BytesHomogeneousUint64_a21 = a21;
+  returnStruct1024BytesHomogeneousUint64_a22 = a22;
+  returnStruct1024BytesHomogeneousUint64_a23 = a23;
+  returnStruct1024BytesHomogeneousUint64_a24 = a24;
+  returnStruct1024BytesHomogeneousUint64_a25 = a25;
+  returnStruct1024BytesHomogeneousUint64_a26 = a26;
+  returnStruct1024BytesHomogeneousUint64_a27 = a27;
+  returnStruct1024BytesHomogeneousUint64_a28 = a28;
+  returnStruct1024BytesHomogeneousUint64_a29 = a29;
+  returnStruct1024BytesHomogeneousUint64_a30 = a30;
+  returnStruct1024BytesHomogeneousUint64_a31 = a31;
+  returnStruct1024BytesHomogeneousUint64_a32 = a32;
+  returnStruct1024BytesHomogeneousUint64_a33 = a33;
+  returnStruct1024BytesHomogeneousUint64_a34 = a34;
+  returnStruct1024BytesHomogeneousUint64_a35 = a35;
+  returnStruct1024BytesHomogeneousUint64_a36 = a36;
+  returnStruct1024BytesHomogeneousUint64_a37 = a37;
+  returnStruct1024BytesHomogeneousUint64_a38 = a38;
+  returnStruct1024BytesHomogeneousUint64_a39 = a39;
+  returnStruct1024BytesHomogeneousUint64_a40 = a40;
+  returnStruct1024BytesHomogeneousUint64_a41 = a41;
+  returnStruct1024BytesHomogeneousUint64_a42 = a42;
+  returnStruct1024BytesHomogeneousUint64_a43 = a43;
+  returnStruct1024BytesHomogeneousUint64_a44 = a44;
+  returnStruct1024BytesHomogeneousUint64_a45 = a45;
+  returnStruct1024BytesHomogeneousUint64_a46 = a46;
+  returnStruct1024BytesHomogeneousUint64_a47 = a47;
+  returnStruct1024BytesHomogeneousUint64_a48 = a48;
+  returnStruct1024BytesHomogeneousUint64_a49 = a49;
+  returnStruct1024BytesHomogeneousUint64_a50 = a50;
+  returnStruct1024BytesHomogeneousUint64_a51 = a51;
+  returnStruct1024BytesHomogeneousUint64_a52 = a52;
+  returnStruct1024BytesHomogeneousUint64_a53 = a53;
+  returnStruct1024BytesHomogeneousUint64_a54 = a54;
+  returnStruct1024BytesHomogeneousUint64_a55 = a55;
+  returnStruct1024BytesHomogeneousUint64_a56 = a56;
+  returnStruct1024BytesHomogeneousUint64_a57 = a57;
+  returnStruct1024BytesHomogeneousUint64_a58 = a58;
+  returnStruct1024BytesHomogeneousUint64_a59 = a59;
+  returnStruct1024BytesHomogeneousUint64_a60 = a60;
+  returnStruct1024BytesHomogeneousUint64_a61 = a61;
+  returnStruct1024BytesHomogeneousUint64_a62 = a62;
+  returnStruct1024BytesHomogeneousUint64_a63 = a63;
+  returnStruct1024BytesHomogeneousUint64_a64 = a64;
+  returnStruct1024BytesHomogeneousUint64_a65 = a65;
+  returnStruct1024BytesHomogeneousUint64_a66 = a66;
+  returnStruct1024BytesHomogeneousUint64_a67 = a67;
+  returnStruct1024BytesHomogeneousUint64_a68 = a68;
+  returnStruct1024BytesHomogeneousUint64_a69 = a69;
+  returnStruct1024BytesHomogeneousUint64_a70 = a70;
+  returnStruct1024BytesHomogeneousUint64_a71 = a71;
+  returnStruct1024BytesHomogeneousUint64_a72 = a72;
+  returnStruct1024BytesHomogeneousUint64_a73 = a73;
+  returnStruct1024BytesHomogeneousUint64_a74 = a74;
+  returnStruct1024BytesHomogeneousUint64_a75 = a75;
+  returnStruct1024BytesHomogeneousUint64_a76 = a76;
+  returnStruct1024BytesHomogeneousUint64_a77 = a77;
+  returnStruct1024BytesHomogeneousUint64_a78 = a78;
+  returnStruct1024BytesHomogeneousUint64_a79 = a79;
+  returnStruct1024BytesHomogeneousUint64_a80 = a80;
+  returnStruct1024BytesHomogeneousUint64_a81 = a81;
+  returnStruct1024BytesHomogeneousUint64_a82 = a82;
+  returnStruct1024BytesHomogeneousUint64_a83 = a83;
+  returnStruct1024BytesHomogeneousUint64_a84 = a84;
+  returnStruct1024BytesHomogeneousUint64_a85 = a85;
+  returnStruct1024BytesHomogeneousUint64_a86 = a86;
+  returnStruct1024BytesHomogeneousUint64_a87 = a87;
+  returnStruct1024BytesHomogeneousUint64_a88 = a88;
+  returnStruct1024BytesHomogeneousUint64_a89 = a89;
+  returnStruct1024BytesHomogeneousUint64_a90 = a90;
+  returnStruct1024BytesHomogeneousUint64_a91 = a91;
+  returnStruct1024BytesHomogeneousUint64_a92 = a92;
+  returnStruct1024BytesHomogeneousUint64_a93 = a93;
+  returnStruct1024BytesHomogeneousUint64_a94 = a94;
+  returnStruct1024BytesHomogeneousUint64_a95 = a95;
+  returnStruct1024BytesHomogeneousUint64_a96 = a96;
+  returnStruct1024BytesHomogeneousUint64_a97 = a97;
+  returnStruct1024BytesHomogeneousUint64_a98 = a98;
+  returnStruct1024BytesHomogeneousUint64_a99 = a99;
+  returnStruct1024BytesHomogeneousUint64_a100 = a100;
+  returnStruct1024BytesHomogeneousUint64_a101 = a101;
+  returnStruct1024BytesHomogeneousUint64_a102 = a102;
+  returnStruct1024BytesHomogeneousUint64_a103 = a103;
+  returnStruct1024BytesHomogeneousUint64_a104 = a104;
+  returnStruct1024BytesHomogeneousUint64_a105 = a105;
+  returnStruct1024BytesHomogeneousUint64_a106 = a106;
+  returnStruct1024BytesHomogeneousUint64_a107 = a107;
+  returnStruct1024BytesHomogeneousUint64_a108 = a108;
+  returnStruct1024BytesHomogeneousUint64_a109 = a109;
+  returnStruct1024BytesHomogeneousUint64_a110 = a110;
+  returnStruct1024BytesHomogeneousUint64_a111 = a111;
+  returnStruct1024BytesHomogeneousUint64_a112 = a112;
+  returnStruct1024BytesHomogeneousUint64_a113 = a113;
+  returnStruct1024BytesHomogeneousUint64_a114 = a114;
+  returnStruct1024BytesHomogeneousUint64_a115 = a115;
+  returnStruct1024BytesHomogeneousUint64_a116 = a116;
+  returnStruct1024BytesHomogeneousUint64_a117 = a117;
+  returnStruct1024BytesHomogeneousUint64_a118 = a118;
+  returnStruct1024BytesHomogeneousUint64_a119 = a119;
+  returnStruct1024BytesHomogeneousUint64_a120 = a120;
+  returnStruct1024BytesHomogeneousUint64_a121 = a121;
+  returnStruct1024BytesHomogeneousUint64_a122 = a122;
+  returnStruct1024BytesHomogeneousUint64_a123 = a123;
+  returnStruct1024BytesHomogeneousUint64_a124 = a124;
+  returnStruct1024BytesHomogeneousUint64_a125 = a125;
+  returnStruct1024BytesHomogeneousUint64_a126 = a126;
+  returnStruct1024BytesHomogeneousUint64_a127 = a127;
+
+  final result = returnStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct1024BytesHomogeneousUint64AfterCallback() {
+  free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+
+  final result = returnStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+}
+
+typedef ReturnStructArgumentStruct1ByteIntType = Struct1ByteInt Function(
+    Struct1ByteInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct1ByteInt returnStructArgumentStruct1ByteInt_a0 = Struct1ByteInt();
+
+// Result variable also global, so we can delete it after the callback.
+Struct1ByteInt returnStructArgumentStruct1ByteIntResult = Struct1ByteInt();
+
+Struct1ByteInt returnStructArgumentStruct1ByteIntCalculateResult() {
+  Struct1ByteInt result = returnStructArgumentStruct1ByteInt_a0;
+
+  returnStructArgumentStruct1ByteIntResult = result;
+
+  return result;
+}
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in int registers in most ABIs.
+Struct1ByteInt returnStructArgumentStruct1ByteInt(Struct1ByteInt a0) {
+  print("returnStructArgumentStruct1ByteInt(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructArgumentStruct1ByteInt throwing on purpuse!");
+  }
+
+  returnStructArgumentStruct1ByteInt_a0 = a0;
+
+  final result = returnStructArgumentStruct1ByteIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentStruct1ByteIntAfterCallback() {
+  final result = returnStructArgumentStruct1ByteIntCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentInt32x8Struct1ByteIntType = Struct1ByteInt Function(
+    Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Struct1ByteInt);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructArgumentInt32x8Struct1ByteInt_a0 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a1 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a2 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a3 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a4 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a5 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a6 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a7 = 0;
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteInt_a8 = Struct1ByteInt();
+
+// Result variable also global, so we can delete it after the callback.
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteIntResult =
+    Struct1ByteInt();
+
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteIntCalculateResult() {
+  Struct1ByteInt result = returnStructArgumentInt32x8Struct1ByteInt_a8;
+
+  returnStructArgumentInt32x8Struct1ByteIntResult = result;
+
+  return result;
+}
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed on stack on all ABIs.
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteInt(int a0, int a1, int a2,
+    int a3, int a4, int a5, int a6, int a7, Struct1ByteInt a8) {
+  print(
+      "returnStructArgumentInt32x8Struct1ByteInt(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentInt32x8Struct1ByteInt throwing on purpuse!");
+  }
+
+  returnStructArgumentInt32x8Struct1ByteInt_a0 = a0;
+  returnStructArgumentInt32x8Struct1ByteInt_a1 = a1;
+  returnStructArgumentInt32x8Struct1ByteInt_a2 = a2;
+  returnStructArgumentInt32x8Struct1ByteInt_a3 = a3;
+  returnStructArgumentInt32x8Struct1ByteInt_a4 = a4;
+  returnStructArgumentInt32x8Struct1ByteInt_a5 = a5;
+  returnStructArgumentInt32x8Struct1ByteInt_a6 = a6;
+  returnStructArgumentInt32x8Struct1ByteInt_a7 = a7;
+  returnStructArgumentInt32x8Struct1ByteInt_a8 = a8;
+
+  final result = returnStructArgumentInt32x8Struct1ByteIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentInt32x8Struct1ByteIntAfterCallback() {
+  final result = returnStructArgumentInt32x8Struct1ByteIntCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentStruct8BytesHomogeneousFloatType
+    = Struct8BytesHomogeneousFloat Function(Struct8BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesHomogeneousFloat
+    returnStructArgumentStruct8BytesHomogeneousFloat_a0 =
+    Struct8BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesHomogeneousFloat
+    returnStructArgumentStruct8BytesHomogeneousFloatResult =
+    Struct8BytesHomogeneousFloat();
+
+Struct8BytesHomogeneousFloat
+    returnStructArgumentStruct8BytesHomogeneousFloatCalculateResult() {
+  Struct8BytesHomogeneousFloat result =
+      returnStructArgumentStruct8BytesHomogeneousFloat_a0;
+
+  returnStructArgumentStruct8BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in float registers in most ABIs.
+Struct8BytesHomogeneousFloat returnStructArgumentStruct8BytesHomogeneousFloat(
+    Struct8BytesHomogeneousFloat a0) {
+  print("returnStructArgumentStruct8BytesHomogeneousFloat(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentStruct8BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStructArgumentStruct8BytesHomogeneousFloat_a0 = a0;
+
+  final result =
+      returnStructArgumentStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentStruct8BytesHomogeneousFloatAfterCallback() {
+  final result =
+      returnStructArgumentStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentStruct20BytesHomogeneousInt32Type
+    = Struct20BytesHomogeneousInt32 Function(Struct20BytesHomogeneousInt32);
+
+// Global variables to be able to test inputs after callback returned.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentStruct20BytesHomogeneousInt32_a0 =
+    Struct20BytesHomogeneousInt32();
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentStruct20BytesHomogeneousInt32Result =
+    Struct20BytesHomogeneousInt32();
+
+Struct20BytesHomogeneousInt32
+    returnStructArgumentStruct20BytesHomogeneousInt32CalculateResult() {
+  Struct20BytesHomogeneousInt32 result =
+      returnStructArgumentStruct20BytesHomogeneousInt32_a0;
+
+  returnStructArgumentStruct20BytesHomogeneousInt32Result = result;
+
+  return result;
+}
+
+/// On arm64, both argument and return value are passed in by pointer.
+Struct20BytesHomogeneousInt32 returnStructArgumentStruct20BytesHomogeneousInt32(
+    Struct20BytesHomogeneousInt32 a0) {
+  print("returnStructArgumentStruct20BytesHomogeneousInt32(${a0})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentStruct20BytesHomogeneousInt32 throwing on purpuse!");
+  }
+
+  returnStructArgumentStruct20BytesHomogeneousInt32_a0 = a0;
+
+  final result =
+      returnStructArgumentStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentStruct20BytesHomogeneousInt32AfterCallback() {
+  final result =
+      returnStructArgumentStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentInt32x8Struct20BytesHomogeneouType
+    = Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32, Int32,
+        Int32, Int32, Int32, Struct20BytesHomogeneousInt32);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a0 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a1 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a2 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a3 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a4 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a5 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a6 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a7 = 0;
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneou_a8 =
+    Struct20BytesHomogeneousInt32();
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneouResult =
+    Struct20BytesHomogeneousInt32();
+
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneouCalculateResult() {
+  Struct20BytesHomogeneousInt32 result =
+      returnStructArgumentInt32x8Struct20BytesHomogeneou_a8;
+
+  returnStructArgumentInt32x8Struct20BytesHomogeneouResult = result;
+
+  return result;
+}
+
+/// On arm64, both argument and return value are passed in by pointer.
+/// Ints exhaust registers, so that pointer is passed on stack.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneou(
+        int a0,
+        int a1,
+        int a2,
+        int a3,
+        int a4,
+        int a5,
+        int a6,
+        int a7,
+        Struct20BytesHomogeneousInt32 a8) {
+  print(
+      "returnStructArgumentInt32x8Struct20BytesHomogeneou(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentInt32x8Struct20BytesHomogeneou throwing on purpuse!");
+  }
+
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a0 = a0;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a1 = a1;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a2 = a2;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a3 = a3;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a4 = a4;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a5 = a5;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a6 = a6;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a7 = a7;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a8 = a8;
+
+  final result =
+      returnStructArgumentInt32x8Struct20BytesHomogeneouCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentInt32x8Struct20BytesHomogeneouAfterCallback() {
+  final result =
+      returnStructArgumentInt32x8Struct20BytesHomogeneouCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructAlignmentInt16Type = StructAlignmentInt16 Function(
+    Int8, Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructAlignmentInt16_a0 = 0;
+int returnStructAlignmentInt16_a1 = 0;
+int returnStructAlignmentInt16_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+StructAlignmentInt16 returnStructAlignmentInt16Result = StructAlignmentInt16();
+
+StructAlignmentInt16 returnStructAlignmentInt16CalculateResult() {
+  StructAlignmentInt16 result = allocate<StructAlignmentInt16>().ref;
+
+  result.a0 = returnStructAlignmentInt16_a0;
+  result.a1 = returnStructAlignmentInt16_a1;
+  result.a2 = returnStructAlignmentInt16_a2;
+
+  returnStructAlignmentInt16Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 16 byte int within struct.
+StructAlignmentInt16 returnStructAlignmentInt16(int a0, int a1, int a2) {
+  print("returnStructAlignmentInt16(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructAlignmentInt16 throwing on purpuse!");
+  }
+
+  returnStructAlignmentInt16_a0 = a0;
+  returnStructAlignmentInt16_a1 = a1;
+  returnStructAlignmentInt16_a2 = a2;
+
+  final result = returnStructAlignmentInt16CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructAlignmentInt16AfterCallback() {
+  free(returnStructAlignmentInt16Result.addressOf);
+
+  final result = returnStructAlignmentInt16CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStructAlignmentInt16Result.addressOf);
+}
+
+typedef ReturnStructAlignmentInt32Type = StructAlignmentInt32 Function(
+    Int8, Int32, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructAlignmentInt32_a0 = 0;
+int returnStructAlignmentInt32_a1 = 0;
+int returnStructAlignmentInt32_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+StructAlignmentInt32 returnStructAlignmentInt32Result = StructAlignmentInt32();
+
+StructAlignmentInt32 returnStructAlignmentInt32CalculateResult() {
+  StructAlignmentInt32 result = allocate<StructAlignmentInt32>().ref;
+
+  result.a0 = returnStructAlignmentInt32_a0;
+  result.a1 = returnStructAlignmentInt32_a1;
+  result.a2 = returnStructAlignmentInt32_a2;
+
+  returnStructAlignmentInt32Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 32 byte int within struct.
+StructAlignmentInt32 returnStructAlignmentInt32(int a0, int a1, int a2) {
+  print("returnStructAlignmentInt32(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructAlignmentInt32 throwing on purpuse!");
+  }
+
+  returnStructAlignmentInt32_a0 = a0;
+  returnStructAlignmentInt32_a1 = a1;
+  returnStructAlignmentInt32_a2 = a2;
+
+  final result = returnStructAlignmentInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructAlignmentInt32AfterCallback() {
+  free(returnStructAlignmentInt32Result.addressOf);
+
+  final result = returnStructAlignmentInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStructAlignmentInt32Result.addressOf);
+}
+
+typedef ReturnStructAlignmentInt64Type = StructAlignmentInt64 Function(
+    Int8, Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructAlignmentInt64_a0 = 0;
+int returnStructAlignmentInt64_a1 = 0;
+int returnStructAlignmentInt64_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+StructAlignmentInt64 returnStructAlignmentInt64Result = StructAlignmentInt64();
+
+StructAlignmentInt64 returnStructAlignmentInt64CalculateResult() {
+  StructAlignmentInt64 result = allocate<StructAlignmentInt64>().ref;
+
+  result.a0 = returnStructAlignmentInt64_a0;
+  result.a1 = returnStructAlignmentInt64_a1;
+  result.a2 = returnStructAlignmentInt64_a2;
+
+  returnStructAlignmentInt64Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 64 byte int within struct.
+StructAlignmentInt64 returnStructAlignmentInt64(int a0, int a1, int a2) {
+  print("returnStructAlignmentInt64(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructAlignmentInt64 throwing on purpuse!");
+  }
+
+  returnStructAlignmentInt64_a0 = a0;
+  returnStructAlignmentInt64_a1 = a1;
+  returnStructAlignmentInt64_a2 = a2;
+
+  final result = returnStructAlignmentInt64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructAlignmentInt64AfterCallback() {
+  free(returnStructAlignmentInt64Result.addressOf);
+
+  final result = returnStructAlignmentInt64CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStructAlignmentInt64Result.addressOf);
+}
diff --git a/tests/ffi/function_callbacks_structs_by_value_test.dart b/tests/ffi/function_callbacks_structs_by_value_test.dart
new file mode 100644
index 0000000..98ab518
--- /dev/null
+++ b/tests/ffi/function_callbacks_structs_by_value_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2020, 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
+//
+// VMOptions=--deterministic --optimization-counter-threshold=5 --use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+// Reuse the struct classes.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  for (int i = 0; i < 10; i++) {
+    recursiveTest(10);
+    recursiveTest(11);
+  }
+}
+
+void recursiveTest(int recursionCounter) {
+  final struct = allocate<Struct20BytesHomogeneousInt32>().ref;
+  struct.a0 = 1;
+  struct.a1 = 2;
+  struct.a2 = 3;
+  struct.a3 = 4;
+  struct.a4 = 5;
+  final result = dartPassStructRecursive(recursionCounter, struct);
+  Expect.equals(struct.a0 + recursionCounter * 2, result.a0);
+  Expect.equals(struct.a1, result.a1);
+  Expect.equals(struct.a2, result.a2);
+  Expect.equals(struct.a3, result.a3);
+  Expect.equals(struct.a4, result.a4);
+  free(struct.addressOf);
+}
+
+Struct20BytesHomogeneousInt32 dartPassStructRecursive(
+    int recursionCounter, Struct20BytesHomogeneousInt32 struct) {
+  print("callbackPassStructRecurisive($recursionCounter, $struct)");
+  struct.a0++;
+  final structA0Saved = struct.a0;
+  if (recursionCounter <= 0) {
+    print("returning");
+    return struct;
+  }
+
+  final result =
+      cPassStructRecursive(recursionCounter - 1, struct, functionPointer);
+  result.a0++;
+
+  // Check struct.a0 is not modified by Dart->C call.
+  Expect.equals(structA0Saved, struct.a0);
+
+  // Check struct.a0 is not modified by C->Dart callback, if so struct.a4 == 0.
+  Expect.notEquals(0, struct.a4);
+
+  return result;
+}
+
+final functionPointer = Pointer.fromFunction<
+    Struct20BytesHomogeneousInt32 Function(
+        Int64, Struct20BytesHomogeneousInt32)>(dartPassStructRecursive);
+
+final cPassStructRecursive = ffiTestFunctions.lookupFunction<
+    Struct20BytesHomogeneousInt32 Function(Int64 recursionCounter,
+        Struct20BytesHomogeneousInt32 struct, Pointer callbackAddress),
+    Struct20BytesHomogeneousInt32 Function(int recursionCounter,
+        Struct20BytesHomogeneousInt32, Pointer)>("PassStructRecursive");
diff --git a/tests/ffi/function_structs_by_value_generated_test.dart b/tests/ffi/function_structs_by_value_generated_test.dart
new file mode 100644
index 0000000..3cbdf98
--- /dev/null
+++ b/tests/ffi/function_structs_by_value_generated_test.dart
@@ -0,0 +1,4720 @@
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=5
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'dylib_utils.dart';
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+void main() {
+  for (int i = 0; i < 10; ++i) {
+    testPassStruct1ByteIntx10();
+    testPassStruct3BytesIntx10();
+    testPassStruct4BytesHomogeneousInt16x10();
+    testPassStruct7BytesIntx10();
+    testPassStruct8BytesIntx10();
+    testPassStruct8BytesHomogeneousFloatx10();
+    testPassStruct8BytesMixedx10();
+    testPassStruct9BytesIntx10();
+    testPassStruct9BytesHomogeneousUint82x10();
+    testPassStruct12BytesHomogeneousFloatx6();
+    testPassStruct16BytesHomogeneousFloatx5();
+    testPassStruct16BytesMixedx10();
+    testPassStruct16BytesMixed2x10();
+    testPassStruct17BytesIntx10();
+    testPassStruct19BytesHomogeneousUint8x10();
+    testPassStruct20BytesHomogeneousInt32x10();
+    testPassStruct20BytesHomogeneousFloat();
+    testPassStruct32BytesHomogeneousDoublex5();
+    testPassStruct40BytesHomogeneousDouble();
+    testPassStruct1024BytesHomogeneousUint64();
+    testPassFloatStruct16BytesHomogeneousFloatFloatStruct1();
+    testPassFloatStruct32BytesHomogeneousDoubleFloatStruct();
+    testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn();
+    testPassDoublex6Struct16BytesMixedx4Int32();
+    testPassInt32x4Struct16BytesMixedx4Double();
+    testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo();
+    testPassStructAlignmentInt16();
+    testPassStructAlignmentInt32();
+    testPassStructAlignmentInt64();
+    testReturnStruct1ByteInt();
+    testReturnStruct3BytesInt();
+    testReturnStruct4BytesHomogeneousInt16();
+    testReturnStruct7BytesInt();
+    testReturnStruct8BytesInt();
+    testReturnStruct8BytesHomogeneousFloat();
+    testReturnStruct8BytesMixed();
+    testReturnStruct9BytesInt();
+    testReturnStruct9BytesHomogeneousUint82();
+    testReturnStruct12BytesHomogeneousFloat();
+    testReturnStruct16BytesHomogeneousFloat();
+    testReturnStruct16BytesMixed();
+    testReturnStruct16BytesMixed2();
+    testReturnStruct17BytesInt();
+    testReturnStruct19BytesHomogeneousUint8();
+    testReturnStruct20BytesHomogeneousInt32();
+    testReturnStruct20BytesHomogeneousFloat();
+    testReturnStruct32BytesHomogeneousDouble();
+    testReturnStruct40BytesHomogeneousDouble();
+    testReturnStruct1024BytesHomogeneousUint64();
+    testReturnStructArgumentStruct1ByteInt();
+    testReturnStructArgumentInt32x8Struct1ByteInt();
+    testReturnStructArgumentStruct8BytesHomogeneousFloat();
+    testReturnStructArgumentStruct20BytesHomogeneousInt32();
+    testReturnStructArgumentInt32x8Struct20BytesHomogeneou();
+    testReturnStructAlignmentInt16();
+    testReturnStructAlignmentInt32();
+    testReturnStructAlignmentInt64();
+  }
+}
+
+class Struct0Bytes extends Struct {
+  String toString() => "()";
+}
+
+class Struct1ByteInt extends Struct {
+  @Int8()
+  external int a0;
+
+  String toString() => "(${a0})";
+}
+
+class Struct3BytesInt extends Struct {
+  @Int16()
+  external int a0;
+
+  @Int8()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct4BytesHomogeneousInt16 extends Struct {
+  @Int16()
+  external int a0;
+
+  @Int16()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct7BytesInt extends Struct {
+  @Int32()
+  external int a0;
+
+  @Int16()
+  external int a1;
+
+  @Int8()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct8BytesInt extends Struct {
+  @Int16()
+  external int a0;
+
+  @Int16()
+  external int a1;
+
+  @Int32()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct8BytesHomogeneousFloat extends Struct {
+  @Float()
+  external double a0;
+
+  @Float()
+  external double a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct8BytesMixed extends Struct {
+  @Float()
+  external double a0;
+
+  @Int16()
+  external int a1;
+
+  @Int16()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct9BytesInt extends Struct {
+  @Int64()
+  external int a0;
+
+  @Int8()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct9BytesHomogeneousUint82 extends Struct {
+  @Uint8()
+  external int a0;
+
+  @Uint8()
+  external int a1;
+
+  @Uint8()
+  external int a2;
+
+  @Uint8()
+  external int a3;
+
+  @Uint8()
+  external int a4;
+
+  @Uint8()
+  external int a5;
+
+  @Uint8()
+  external int a6;
+
+  @Uint8()
+  external int a7;
+
+  @Uint8()
+  external int a8;
+
+  String toString() =>
+      "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})";
+}
+
+class Struct12BytesHomogeneousFloat extends Struct {
+  @Float()
+  external double a0;
+
+  @Float()
+  external double a1;
+
+  @Float()
+  external double a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct16BytesHomogeneousFloat extends Struct {
+  @Float()
+  external double a0;
+
+  @Float()
+  external double a1;
+
+  @Float()
+  external double a2;
+
+  @Float()
+  external double a3;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3})";
+}
+
+class Struct16BytesMixed extends Struct {
+  @Double()
+  external double a0;
+
+  @Int64()
+  external int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct16BytesMixed2 extends Struct {
+  @Float()
+  external double a0;
+
+  @Float()
+  external double a1;
+
+  @Float()
+  external double a2;
+
+  @Int32()
+  external int a3;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3})";
+}
+
+class Struct17BytesInt extends Struct {
+  @Int64()
+  external int a0;
+
+  @Int64()
+  external int a1;
+
+  @Int8()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct19BytesHomogeneousUint8 extends Struct {
+  @Uint8()
+  external int a0;
+
+  @Uint8()
+  external int a1;
+
+  @Uint8()
+  external int a2;
+
+  @Uint8()
+  external int a3;
+
+  @Uint8()
+  external int a4;
+
+  @Uint8()
+  external int a5;
+
+  @Uint8()
+  external int a6;
+
+  @Uint8()
+  external int a7;
+
+  @Uint8()
+  external int a8;
+
+  @Uint8()
+  external int a9;
+
+  @Uint8()
+  external int a10;
+
+  @Uint8()
+  external int a11;
+
+  @Uint8()
+  external int a12;
+
+  @Uint8()
+  external int a13;
+
+  @Uint8()
+  external int a14;
+
+  @Uint8()
+  external int a15;
+
+  @Uint8()
+  external int a16;
+
+  @Uint8()
+  external int a17;
+
+  @Uint8()
+  external int a18;
+
+  String toString() =>
+      "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18})";
+}
+
+class Struct20BytesHomogeneousInt32 extends Struct {
+  @Int32()
+  external int a0;
+
+  @Int32()
+  external int a1;
+
+  @Int32()
+  external int a2;
+
+  @Int32()
+  external int a3;
+
+  @Int32()
+  external int a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+class Struct20BytesHomogeneousFloat extends Struct {
+  @Float()
+  external double a0;
+
+  @Float()
+  external double a1;
+
+  @Float()
+  external double a2;
+
+  @Float()
+  external double a3;
+
+  @Float()
+  external double a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+class Struct32BytesHomogeneousDouble extends Struct {
+  @Double()
+  external double a0;
+
+  @Double()
+  external double a1;
+
+  @Double()
+  external double a2;
+
+  @Double()
+  external double a3;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3})";
+}
+
+class Struct40BytesHomogeneousDouble extends Struct {
+  @Double()
+  external double a0;
+
+  @Double()
+  external double a1;
+
+  @Double()
+  external double a2;
+
+  @Double()
+  external double a3;
+
+  @Double()
+  external double a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+class Struct1024BytesHomogeneousUint64 extends Struct {
+  @Uint64()
+  external int a0;
+
+  @Uint64()
+  external int a1;
+
+  @Uint64()
+  external int a2;
+
+  @Uint64()
+  external int a3;
+
+  @Uint64()
+  external int a4;
+
+  @Uint64()
+  external int a5;
+
+  @Uint64()
+  external int a6;
+
+  @Uint64()
+  external int a7;
+
+  @Uint64()
+  external int a8;
+
+  @Uint64()
+  external int a9;
+
+  @Uint64()
+  external int a10;
+
+  @Uint64()
+  external int a11;
+
+  @Uint64()
+  external int a12;
+
+  @Uint64()
+  external int a13;
+
+  @Uint64()
+  external int a14;
+
+  @Uint64()
+  external int a15;
+
+  @Uint64()
+  external int a16;
+
+  @Uint64()
+  external int a17;
+
+  @Uint64()
+  external int a18;
+
+  @Uint64()
+  external int a19;
+
+  @Uint64()
+  external int a20;
+
+  @Uint64()
+  external int a21;
+
+  @Uint64()
+  external int a22;
+
+  @Uint64()
+  external int a23;
+
+  @Uint64()
+  external int a24;
+
+  @Uint64()
+  external int a25;
+
+  @Uint64()
+  external int a26;
+
+  @Uint64()
+  external int a27;
+
+  @Uint64()
+  external int a28;
+
+  @Uint64()
+  external int a29;
+
+  @Uint64()
+  external int a30;
+
+  @Uint64()
+  external int a31;
+
+  @Uint64()
+  external int a32;
+
+  @Uint64()
+  external int a33;
+
+  @Uint64()
+  external int a34;
+
+  @Uint64()
+  external int a35;
+
+  @Uint64()
+  external int a36;
+
+  @Uint64()
+  external int a37;
+
+  @Uint64()
+  external int a38;
+
+  @Uint64()
+  external int a39;
+
+  @Uint64()
+  external int a40;
+
+  @Uint64()
+  external int a41;
+
+  @Uint64()
+  external int a42;
+
+  @Uint64()
+  external int a43;
+
+  @Uint64()
+  external int a44;
+
+  @Uint64()
+  external int a45;
+
+  @Uint64()
+  external int a46;
+
+  @Uint64()
+  external int a47;
+
+  @Uint64()
+  external int a48;
+
+  @Uint64()
+  external int a49;
+
+  @Uint64()
+  external int a50;
+
+  @Uint64()
+  external int a51;
+
+  @Uint64()
+  external int a52;
+
+  @Uint64()
+  external int a53;
+
+  @Uint64()
+  external int a54;
+
+  @Uint64()
+  external int a55;
+
+  @Uint64()
+  external int a56;
+
+  @Uint64()
+  external int a57;
+
+  @Uint64()
+  external int a58;
+
+  @Uint64()
+  external int a59;
+
+  @Uint64()
+  external int a60;
+
+  @Uint64()
+  external int a61;
+
+  @Uint64()
+  external int a62;
+
+  @Uint64()
+  external int a63;
+
+  @Uint64()
+  external int a64;
+
+  @Uint64()
+  external int a65;
+
+  @Uint64()
+  external int a66;
+
+  @Uint64()
+  external int a67;
+
+  @Uint64()
+  external int a68;
+
+  @Uint64()
+  external int a69;
+
+  @Uint64()
+  external int a70;
+
+  @Uint64()
+  external int a71;
+
+  @Uint64()
+  external int a72;
+
+  @Uint64()
+  external int a73;
+
+  @Uint64()
+  external int a74;
+
+  @Uint64()
+  external int a75;
+
+  @Uint64()
+  external int a76;
+
+  @Uint64()
+  external int a77;
+
+  @Uint64()
+  external int a78;
+
+  @Uint64()
+  external int a79;
+
+  @Uint64()
+  external int a80;
+
+  @Uint64()
+  external int a81;
+
+  @Uint64()
+  external int a82;
+
+  @Uint64()
+  external int a83;
+
+  @Uint64()
+  external int a84;
+
+  @Uint64()
+  external int a85;
+
+  @Uint64()
+  external int a86;
+
+  @Uint64()
+  external int a87;
+
+  @Uint64()
+  external int a88;
+
+  @Uint64()
+  external int a89;
+
+  @Uint64()
+  external int a90;
+
+  @Uint64()
+  external int a91;
+
+  @Uint64()
+  external int a92;
+
+  @Uint64()
+  external int a93;
+
+  @Uint64()
+  external int a94;
+
+  @Uint64()
+  external int a95;
+
+  @Uint64()
+  external int a96;
+
+  @Uint64()
+  external int a97;
+
+  @Uint64()
+  external int a98;
+
+  @Uint64()
+  external int a99;
+
+  @Uint64()
+  external int a100;
+
+  @Uint64()
+  external int a101;
+
+  @Uint64()
+  external int a102;
+
+  @Uint64()
+  external int a103;
+
+  @Uint64()
+  external int a104;
+
+  @Uint64()
+  external int a105;
+
+  @Uint64()
+  external int a106;
+
+  @Uint64()
+  external int a107;
+
+  @Uint64()
+  external int a108;
+
+  @Uint64()
+  external int a109;
+
+  @Uint64()
+  external int a110;
+
+  @Uint64()
+  external int a111;
+
+  @Uint64()
+  external int a112;
+
+  @Uint64()
+  external int a113;
+
+  @Uint64()
+  external int a114;
+
+  @Uint64()
+  external int a115;
+
+  @Uint64()
+  external int a116;
+
+  @Uint64()
+  external int a117;
+
+  @Uint64()
+  external int a118;
+
+  @Uint64()
+  external int a119;
+
+  @Uint64()
+  external int a120;
+
+  @Uint64()
+  external int a121;
+
+  @Uint64()
+  external int a122;
+
+  @Uint64()
+  external int a123;
+
+  @Uint64()
+  external int a124;
+
+  @Uint64()
+  external int a125;
+
+  @Uint64()
+  external int a126;
+
+  @Uint64()
+  external int a127;
+
+  String toString() =>
+      "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18}, ${a19}, ${a20}, ${a21}, ${a22}, ${a23}, ${a24}, ${a25}, ${a26}, ${a27}, ${a28}, ${a29}, ${a30}, ${a31}, ${a32}, ${a33}, ${a34}, ${a35}, ${a36}, ${a37}, ${a38}, ${a39}, ${a40}, ${a41}, ${a42}, ${a43}, ${a44}, ${a45}, ${a46}, ${a47}, ${a48}, ${a49}, ${a50}, ${a51}, ${a52}, ${a53}, ${a54}, ${a55}, ${a56}, ${a57}, ${a58}, ${a59}, ${a60}, ${a61}, ${a62}, ${a63}, ${a64}, ${a65}, ${a66}, ${a67}, ${a68}, ${a69}, ${a70}, ${a71}, ${a72}, ${a73}, ${a74}, ${a75}, ${a76}, ${a77}, ${a78}, ${a79}, ${a80}, ${a81}, ${a82}, ${a83}, ${a84}, ${a85}, ${a86}, ${a87}, ${a88}, ${a89}, ${a90}, ${a91}, ${a92}, ${a93}, ${a94}, ${a95}, ${a96}, ${a97}, ${a98}, ${a99}, ${a100}, ${a101}, ${a102}, ${a103}, ${a104}, ${a105}, ${a106}, ${a107}, ${a108}, ${a109}, ${a110}, ${a111}, ${a112}, ${a113}, ${a114}, ${a115}, ${a116}, ${a117}, ${a118}, ${a119}, ${a120}, ${a121}, ${a122}, ${a123}, ${a124}, ${a125}, ${a126}, ${a127})";
+}
+
+class StructAlignmentInt16 extends Struct {
+  @Int8()
+  external int a0;
+
+  @Int16()
+  external int a1;
+
+  @Int8()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class StructAlignmentInt32 extends Struct {
+  @Int8()
+  external int a0;
+
+  @Int32()
+  external int a1;
+
+  @Int8()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class StructAlignmentInt64 extends Struct {
+  @Int8()
+  external int a0;
+
+  @Int64()
+  external int a1;
+
+  @Int8()
+  external int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+final passStruct1ByteIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt),
+    int Function(
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt)>("PassStruct1ByteIntx10");
+
+/// Smallest struct with data.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct1ByteIntx10() {
+  Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a1 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a2 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a3 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a4 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a5 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a6 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a7 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a9 = allocate<Struct1ByteInt>().ref;
+
+  a0.a0 = -1;
+  a1.a0 = 2;
+  a2.a0 = -3;
+  a3.a0 = 4;
+  a4.a0 = -5;
+  a5.a0 = 6;
+  a6.a0 = -7;
+  a7.a0 = 8;
+  a8.a0 = -9;
+  a9.a0 = 10;
+
+  final result = passStruct1ByteIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(5, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct3BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt),
+    int Function(
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt)>("PassStruct3BytesIntx10");
+
+/// Not a multiple of word size, not a power of two.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct3BytesIntx10() {
+  Struct3BytesInt a0 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a1 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a2 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a3 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a4 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a5 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a6 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a7 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a8 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a9 = allocate<Struct3BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result = passStruct3BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct4BytesHomogeneousInt16x10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16),
+    int Function(
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16)>("PassStruct4BytesHomogeneousInt16x10");
+
+/// Exactly word size on 32-bit architectures.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct4BytesHomogeneousInt16x10() {
+  Struct4BytesHomogeneousInt16 a0 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a1 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a2 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a3 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a4 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a5 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a6 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a7 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a8 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a9 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result = passStruct4BytesHomogeneousInt16x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct7BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt),
+    int Function(
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt)>("PassStruct7BytesIntx10");
+
+/// Sub word size on 64 bit architectures.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct7BytesIntx10() {
+  Struct7BytesInt a0 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a1 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a2 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a3 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a4 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a5 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a6 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a7 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a8 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a9 = allocate<Struct7BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result = passStruct7BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(15, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct8BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt),
+    int Function(
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt)>("PassStruct8BytesIntx10");
+
+/// Exactly word size struct on 64bit architectures.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct8BytesIntx10() {
+  Struct8BytesInt a0 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a1 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a2 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a3 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a4 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a5 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a6 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a7 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a8 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a9 = allocate<Struct8BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result = passStruct8BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(15, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct8BytesHomogeneousFloatx10 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat),
+    double Function(
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat)>("PassStruct8BytesHomogeneousFloatx10");
+
+/// Arguments passed in FP registers as long as they fit.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct8BytesHomogeneousFloatx10() {
+  Struct8BytesHomogeneousFloat a0 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a1 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a2 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a3 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a4 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a5 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a6 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a7 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a8 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a9 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a1.a0 = -3.0;
+  a1.a1 = 4.0;
+  a2.a0 = -5.0;
+  a2.a1 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a4.a0 = -9.0;
+  a4.a1 = 10.0;
+  a5.a0 = -11.0;
+  a5.a1 = 12.0;
+  a6.a0 = -13.0;
+  a6.a1 = 14.0;
+  a7.a0 = -15.0;
+  a7.a1 = 16.0;
+  a8.a0 = -17.0;
+  a8.a1 = 18.0;
+  a9.a0 = -19.0;
+  a9.a1 = 20.0;
+
+  final result = passStruct8BytesHomogeneousFloatx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct8BytesMixedx10 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed),
+    double Function(
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed)>("PassStruct8BytesMixedx10");
+
+/// On x64, arguments go in int registers because it is not only float.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct8BytesMixedx10() {
+  Struct8BytesMixed a0 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a1 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a2 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a3 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a4 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a5 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a6 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a7 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a8 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a9 = allocate<Struct8BytesMixed>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4.0;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7.0;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10.0;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13.0;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16.0;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19.0;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22.0;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25.0;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28.0;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result =
+      passStruct8BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(15.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct9BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt),
+    int Function(
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt)>("PassStruct9BytesIntx10");
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+void testPassStruct9BytesIntx10() {
+  Struct9BytesInt a0 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a1 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a2 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a3 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a4 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a5 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a6 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a7 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a8 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a9 = allocate<Struct9BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result = passStruct9BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct9BytesHomogeneousUint82x10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82),
+    int Function(
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82)>("PassStruct9BytesHomogeneousUint82x10");
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Struct only has 1-byte aligned fields to test struct alignment itself.
+///
+void testPassStruct9BytesHomogeneousUint82x10() {
+  Struct9BytesHomogeneousUint82 a0 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a1 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a2 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a3 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a4 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a5 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a6 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a7 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a8 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a9 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a1.a0 = 10;
+  a1.a1 = 11;
+  a1.a2 = 12;
+  a1.a3 = 13;
+  a1.a4 = 14;
+  a1.a5 = 15;
+  a1.a6 = 16;
+  a1.a7 = 17;
+  a1.a8 = 18;
+  a2.a0 = 19;
+  a2.a1 = 20;
+  a2.a2 = 21;
+  a2.a3 = 22;
+  a2.a4 = 23;
+  a2.a5 = 24;
+  a2.a6 = 25;
+  a2.a7 = 26;
+  a2.a8 = 27;
+  a3.a0 = 28;
+  a3.a1 = 29;
+  a3.a2 = 30;
+  a3.a3 = 31;
+  a3.a4 = 32;
+  a3.a5 = 33;
+  a3.a6 = 34;
+  a3.a7 = 35;
+  a3.a8 = 36;
+  a4.a0 = 37;
+  a4.a1 = 38;
+  a4.a2 = 39;
+  a4.a3 = 40;
+  a4.a4 = 41;
+  a4.a5 = 42;
+  a4.a6 = 43;
+  a4.a7 = 44;
+  a4.a8 = 45;
+  a5.a0 = 46;
+  a5.a1 = 47;
+  a5.a2 = 48;
+  a5.a3 = 49;
+  a5.a4 = 50;
+  a5.a5 = 51;
+  a5.a6 = 52;
+  a5.a7 = 53;
+  a5.a8 = 54;
+  a6.a0 = 55;
+  a6.a1 = 56;
+  a6.a2 = 57;
+  a6.a3 = 58;
+  a6.a4 = 59;
+  a6.a5 = 60;
+  a6.a6 = 61;
+  a6.a7 = 62;
+  a6.a8 = 63;
+  a7.a0 = 64;
+  a7.a1 = 65;
+  a7.a2 = 66;
+  a7.a3 = 67;
+  a7.a4 = 68;
+  a7.a5 = 69;
+  a7.a6 = 70;
+  a7.a7 = 71;
+  a7.a8 = 72;
+  a8.a0 = 73;
+  a8.a1 = 74;
+  a8.a2 = 75;
+  a8.a3 = 76;
+  a8.a4 = 77;
+  a8.a5 = 78;
+  a8.a6 = 79;
+  a8.a7 = 80;
+  a8.a8 = 81;
+  a9.a0 = 82;
+  a9.a1 = 83;
+  a9.a2 = 84;
+  a9.a3 = 85;
+  a9.a4 = 86;
+  a9.a5 = 87;
+  a9.a6 = 88;
+  a9.a7 = 89;
+  a9.a8 = 90;
+
+  final result = passStruct9BytesHomogeneousUint82x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(4095, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat),
+    double Function(
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat)>("PassStruct12BytesHomogeneousFloatx6");
+
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// Struct arguments will exhaust available registers, and leave some empty.
+/// The last argument is to test whether arguments are backfilled.
+void testPassStruct12BytesHomogeneousFloatx6() {
+  Struct12BytesHomogeneousFloat a0 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a1 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a2 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a3 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a4 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a5 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a1.a0 = 4.0;
+  a1.a1 = -5.0;
+  a1.a2 = 6.0;
+  a2.a0 = -7.0;
+  a2.a1 = 8.0;
+  a2.a2 = -9.0;
+  a3.a0 = 10.0;
+  a3.a1 = -11.0;
+  a3.a2 = 12.0;
+  a4.a0 = -13.0;
+  a4.a1 = 14.0;
+  a4.a2 = -15.0;
+  a5.a0 = 16.0;
+  a5.a1 = -17.0;
+  a5.a2 = 18.0;
+
+  final result = passStruct12BytesHomogeneousFloatx6(a0, a1, a2, a3, a4, a5);
+
+  print("result = $result");
+
+  Expect.approxEquals(9.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+}
+
+final passStruct16BytesHomogeneousFloatx5 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat),
+    double Function(
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat)>("PassStruct16BytesHomogeneousFloatx5");
+
+/// On Linux x64 argument is transferred on stack because it is over 16 bytes.
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// 5 struct arguments will exhaust available registers.
+void testPassStruct16BytesHomogeneousFloatx5() {
+  Struct16BytesHomogeneousFloat a0 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a1 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a2 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a3 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a4 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8.0;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12.0;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16.0;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20.0;
+
+  final result = passStruct16BytesHomogeneousFloatx5(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+}
+
+final passStruct16BytesMixedx10 = ffiTestFunctions.lookupFunction<
+    Double Function(
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed),
+    double Function(
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed)>("PassStruct16BytesMixedx10");
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 8 byte aligned.
+void testPassStruct16BytesMixedx10() {
+  Struct16BytesMixed a0 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a2 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+  a1.a0 = -3.0;
+  a1.a1 = 4;
+  a2.a0 = -5.0;
+  a2.a1 = 6;
+  a3.a0 = -7.0;
+  a3.a1 = 8;
+  a4.a0 = -9.0;
+  a4.a1 = 10;
+  a5.a0 = -11.0;
+  a5.a1 = 12;
+  a6.a0 = -13.0;
+  a6.a1 = 14;
+  a7.a0 = -15.0;
+  a7.a1 = 16;
+  a8.a0 = -17.0;
+  a8.a1 = 18;
+  a9.a0 = -19.0;
+  a9.a1 = 20;
+
+  final result =
+      passStruct16BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct16BytesMixed2x10 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2),
+    double Function(
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2)>("PassStruct16BytesMixed2x10");
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 4 byte aligned.
+void testPassStruct16BytesMixed2x10() {
+  Struct16BytesMixed2 a0 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a1 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a2 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a3 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a4 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a5 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a6 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a7 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a8 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a9 = allocate<Struct16BytesMixed2>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20;
+  a5.a0 = -21.0;
+  a5.a1 = 22.0;
+  a5.a2 = -23.0;
+  a5.a3 = 24;
+  a6.a0 = -25.0;
+  a6.a1 = 26.0;
+  a6.a2 = -27.0;
+  a6.a3 = 28;
+  a7.a0 = -29.0;
+  a7.a1 = 30.0;
+  a7.a2 = -31.0;
+  a7.a3 = 32;
+  a8.a0 = -33.0;
+  a8.a1 = 34.0;
+  a8.a2 = -35.0;
+  a8.a3 = 36;
+  a9.a0 = -37.0;
+  a9.a1 = 38.0;
+  a9.a2 = -39.0;
+  a9.a3 = 40;
+
+  final result =
+      passStruct16BytesMixed2x10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(20.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct17BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt),
+    int Function(
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt)>("PassStruct17BytesIntx10");
+
+/// Arguments are passed as pointer to copy on arm64.
+/// Tests that the memory allocated for copies are rounded up to word size.
+void testPassStruct17BytesIntx10() {
+  Struct17BytesInt a0 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a1 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a2 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a3 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a4 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a5 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a6 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a7 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a8 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a9 = allocate<Struct17BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result =
+      passStruct17BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(15, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct19BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8),
+    int Function(
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8)>("PassStruct19BytesHomogeneousUint8x10");
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is extended to the right size.
+///
+void testPassStruct19BytesHomogeneousUint8x10() {
+  Struct19BytesHomogeneousUint8 a0 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a1 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a2 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a3 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a4 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a5 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a6 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a7 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a8 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a9 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a0.a9 = 10;
+  a0.a10 = 11;
+  a0.a11 = 12;
+  a0.a12 = 13;
+  a0.a13 = 14;
+  a0.a14 = 15;
+  a0.a15 = 16;
+  a0.a16 = 17;
+  a0.a17 = 18;
+  a0.a18 = 19;
+  a1.a0 = 20;
+  a1.a1 = 21;
+  a1.a2 = 22;
+  a1.a3 = 23;
+  a1.a4 = 24;
+  a1.a5 = 25;
+  a1.a6 = 26;
+  a1.a7 = 27;
+  a1.a8 = 28;
+  a1.a9 = 29;
+  a1.a10 = 30;
+  a1.a11 = 31;
+  a1.a12 = 32;
+  a1.a13 = 33;
+  a1.a14 = 34;
+  a1.a15 = 35;
+  a1.a16 = 36;
+  a1.a17 = 37;
+  a1.a18 = 38;
+  a2.a0 = 39;
+  a2.a1 = 40;
+  a2.a2 = 41;
+  a2.a3 = 42;
+  a2.a4 = 43;
+  a2.a5 = 44;
+  a2.a6 = 45;
+  a2.a7 = 46;
+  a2.a8 = 47;
+  a2.a9 = 48;
+  a2.a10 = 49;
+  a2.a11 = 50;
+  a2.a12 = 51;
+  a2.a13 = 52;
+  a2.a14 = 53;
+  a2.a15 = 54;
+  a2.a16 = 55;
+  a2.a17 = 56;
+  a2.a18 = 57;
+  a3.a0 = 58;
+  a3.a1 = 59;
+  a3.a2 = 60;
+  a3.a3 = 61;
+  a3.a4 = 62;
+  a3.a5 = 63;
+  a3.a6 = 64;
+  a3.a7 = 65;
+  a3.a8 = 66;
+  a3.a9 = 67;
+  a3.a10 = 68;
+  a3.a11 = 69;
+  a3.a12 = 70;
+  a3.a13 = 71;
+  a3.a14 = 72;
+  a3.a15 = 73;
+  a3.a16 = 74;
+  a3.a17 = 75;
+  a3.a18 = 76;
+  a4.a0 = 77;
+  a4.a1 = 78;
+  a4.a2 = 79;
+  a4.a3 = 80;
+  a4.a4 = 81;
+  a4.a5 = 82;
+  a4.a6 = 83;
+  a4.a7 = 84;
+  a4.a8 = 85;
+  a4.a9 = 86;
+  a4.a10 = 87;
+  a4.a11 = 88;
+  a4.a12 = 89;
+  a4.a13 = 90;
+  a4.a14 = 91;
+  a4.a15 = 92;
+  a4.a16 = 93;
+  a4.a17 = 94;
+  a4.a18 = 95;
+  a5.a0 = 96;
+  a5.a1 = 97;
+  a5.a2 = 98;
+  a5.a3 = 99;
+  a5.a4 = 100;
+  a5.a5 = 101;
+  a5.a6 = 102;
+  a5.a7 = 103;
+  a5.a8 = 104;
+  a5.a9 = 105;
+  a5.a10 = 106;
+  a5.a11 = 107;
+  a5.a12 = 108;
+  a5.a13 = 109;
+  a5.a14 = 110;
+  a5.a15 = 111;
+  a5.a16 = 112;
+  a5.a17 = 113;
+  a5.a18 = 114;
+  a6.a0 = 115;
+  a6.a1 = 116;
+  a6.a2 = 117;
+  a6.a3 = 118;
+  a6.a4 = 119;
+  a6.a5 = 120;
+  a6.a6 = 121;
+  a6.a7 = 122;
+  a6.a8 = 123;
+  a6.a9 = 124;
+  a6.a10 = 125;
+  a6.a11 = 126;
+  a6.a12 = 127;
+  a6.a13 = 128;
+  a6.a14 = 129;
+  a6.a15 = 130;
+  a6.a16 = 131;
+  a6.a17 = 132;
+  a6.a18 = 133;
+  a7.a0 = 134;
+  a7.a1 = 135;
+  a7.a2 = 136;
+  a7.a3 = 137;
+  a7.a4 = 138;
+  a7.a5 = 139;
+  a7.a6 = 140;
+  a7.a7 = 141;
+  a7.a8 = 142;
+  a7.a9 = 143;
+  a7.a10 = 144;
+  a7.a11 = 145;
+  a7.a12 = 146;
+  a7.a13 = 147;
+  a7.a14 = 148;
+  a7.a15 = 149;
+  a7.a16 = 150;
+  a7.a17 = 151;
+  a7.a18 = 152;
+  a8.a0 = 153;
+  a8.a1 = 154;
+  a8.a2 = 155;
+  a8.a3 = 156;
+  a8.a4 = 157;
+  a8.a5 = 158;
+  a8.a6 = 159;
+  a8.a7 = 160;
+  a8.a8 = 161;
+  a8.a9 = 162;
+  a8.a10 = 163;
+  a8.a11 = 164;
+  a8.a12 = 165;
+  a8.a13 = 166;
+  a8.a14 = 167;
+  a8.a15 = 168;
+  a8.a16 = 169;
+  a8.a17 = 170;
+  a8.a18 = 171;
+  a9.a0 = 172;
+  a9.a1 = 173;
+  a9.a2 = 174;
+  a9.a3 = 175;
+  a9.a4 = 176;
+  a9.a5 = 177;
+  a9.a6 = 178;
+  a9.a7 = 179;
+  a9.a8 = 180;
+  a9.a9 = 181;
+  a9.a10 = 182;
+  a9.a11 = 183;
+  a9.a12 = 184;
+  a9.a13 = 185;
+  a9.a14 = 186;
+  a9.a15 = 187;
+  a9.a16 = 188;
+  a9.a17 = 189;
+  a9.a18 = 190;
+
+  final result = passStruct19BytesHomogeneousUint8x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(18145, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct20BytesHomogeneousInt32x10 = ffiTestFunctions.lookupFunction<
+    Int32 Function(
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32),
+    int Function(
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32)>("PassStruct20BytesHomogeneousInt32x10");
+
+/// Argument too big to go into integer registers on arm64.
+/// The arguments are passed as pointers to copies.
+/// The amount of arguments exhausts the number of integer registers, such that
+/// pointers to copies are also passed on the stack.
+void testPassStruct20BytesHomogeneousInt32x10() {
+  Struct20BytesHomogeneousInt32 a0 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a1 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a2 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a3 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a4 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a5 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a6 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a7 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a8 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a9 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a0.a3 = 4;
+  a0.a4 = -5;
+  a1.a0 = 6;
+  a1.a1 = -7;
+  a1.a2 = 8;
+  a1.a3 = -9;
+  a1.a4 = 10;
+  a2.a0 = -11;
+  a2.a1 = 12;
+  a2.a2 = -13;
+  a2.a3 = 14;
+  a2.a4 = -15;
+  a3.a0 = 16;
+  a3.a1 = -17;
+  a3.a2 = 18;
+  a3.a3 = -19;
+  a3.a4 = 20;
+  a4.a0 = -21;
+  a4.a1 = 22;
+  a4.a2 = -23;
+  a4.a3 = 24;
+  a4.a4 = -25;
+  a5.a0 = 26;
+  a5.a1 = -27;
+  a5.a2 = 28;
+  a5.a3 = -29;
+  a5.a4 = 30;
+  a6.a0 = -31;
+  a6.a1 = 32;
+  a6.a2 = -33;
+  a6.a3 = 34;
+  a6.a4 = -35;
+  a7.a0 = 36;
+  a7.a1 = -37;
+  a7.a2 = 38;
+  a7.a3 = -39;
+  a7.a4 = 40;
+  a8.a0 = -41;
+  a8.a1 = 42;
+  a8.a2 = -43;
+  a8.a3 = 44;
+  a8.a4 = -45;
+  a9.a0 = 46;
+  a9.a1 = -47;
+  a9.a2 = 48;
+  a9.a3 = -49;
+  a9.a4 = 50;
+
+  final result = passStruct20BytesHomogeneousInt32x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(25, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Float Function(Struct20BytesHomogeneousFloat),
+    double Function(
+        Struct20BytesHomogeneousFloat)>("PassStruct20BytesHomogeneousFloat");
+
+/// Argument too big to go into FPU registers in hardfp and arm64.
+void testPassStruct20BytesHomogeneousFloat() {
+  Struct20BytesHomogeneousFloat a0 =
+      allocate<Struct20BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+
+  final result = passStruct20BytesHomogeneousFloat(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(-3.0, result);
+
+  free(a0.addressOf);
+}
+
+final passStruct32BytesHomogeneousDoublex5 = ffiTestFunctions.lookupFunction<
+        Double Function(
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble),
+        double Function(
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble)>(
+    "PassStruct32BytesHomogeneousDoublex5");
+
+/// Arguments in FPU registers on arm64.
+/// 5 struct arguments will exhaust available registers.
+void testPassStruct32BytesHomogeneousDoublex5() {
+  Struct32BytesHomogeneousDouble a0 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a1 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a2 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a3 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a4 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8.0;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12.0;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16.0;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20.0;
+
+  final result = passStruct32BytesHomogeneousDoublex5(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+}
+
+final passStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
+    Double Function(Struct40BytesHomogeneousDouble),
+    double Function(
+        Struct40BytesHomogeneousDouble)>("PassStruct40BytesHomogeneousDouble");
+
+/// Argument too big to go into FPU registers in arm64.
+void testPassStruct40BytesHomogeneousDouble() {
+  Struct40BytesHomogeneousDouble a0 =
+      allocate<Struct40BytesHomogeneousDouble>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+
+  final result = passStruct40BytesHomogeneousDouble(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(-3.0, result);
+
+  free(a0.addressOf);
+}
+
+final passStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
+        Uint64 Function(Struct1024BytesHomogeneousUint64),
+        int Function(Struct1024BytesHomogeneousUint64)>(
+    "PassStruct1024BytesHomogeneousUint64");
+
+/// Test 1kb struct.
+void testPassStruct1024BytesHomogeneousUint64() {
+  Struct1024BytesHomogeneousUint64 a0 =
+      allocate<Struct1024BytesHomogeneousUint64>().ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a0.a9 = 10;
+  a0.a10 = 11;
+  a0.a11 = 12;
+  a0.a12 = 13;
+  a0.a13 = 14;
+  a0.a14 = 15;
+  a0.a15 = 16;
+  a0.a16 = 17;
+  a0.a17 = 18;
+  a0.a18 = 19;
+  a0.a19 = 20;
+  a0.a20 = 21;
+  a0.a21 = 22;
+  a0.a22 = 23;
+  a0.a23 = 24;
+  a0.a24 = 25;
+  a0.a25 = 26;
+  a0.a26 = 27;
+  a0.a27 = 28;
+  a0.a28 = 29;
+  a0.a29 = 30;
+  a0.a30 = 31;
+  a0.a31 = 32;
+  a0.a32 = 33;
+  a0.a33 = 34;
+  a0.a34 = 35;
+  a0.a35 = 36;
+  a0.a36 = 37;
+  a0.a37 = 38;
+  a0.a38 = 39;
+  a0.a39 = 40;
+  a0.a40 = 41;
+  a0.a41 = 42;
+  a0.a42 = 43;
+  a0.a43 = 44;
+  a0.a44 = 45;
+  a0.a45 = 46;
+  a0.a46 = 47;
+  a0.a47 = 48;
+  a0.a48 = 49;
+  a0.a49 = 50;
+  a0.a50 = 51;
+  a0.a51 = 52;
+  a0.a52 = 53;
+  a0.a53 = 54;
+  a0.a54 = 55;
+  a0.a55 = 56;
+  a0.a56 = 57;
+  a0.a57 = 58;
+  a0.a58 = 59;
+  a0.a59 = 60;
+  a0.a60 = 61;
+  a0.a61 = 62;
+  a0.a62 = 63;
+  a0.a63 = 64;
+  a0.a64 = 65;
+  a0.a65 = 66;
+  a0.a66 = 67;
+  a0.a67 = 68;
+  a0.a68 = 69;
+  a0.a69 = 70;
+  a0.a70 = 71;
+  a0.a71 = 72;
+  a0.a72 = 73;
+  a0.a73 = 74;
+  a0.a74 = 75;
+  a0.a75 = 76;
+  a0.a76 = 77;
+  a0.a77 = 78;
+  a0.a78 = 79;
+  a0.a79 = 80;
+  a0.a80 = 81;
+  a0.a81 = 82;
+  a0.a82 = 83;
+  a0.a83 = 84;
+  a0.a84 = 85;
+  a0.a85 = 86;
+  a0.a86 = 87;
+  a0.a87 = 88;
+  a0.a88 = 89;
+  a0.a89 = 90;
+  a0.a90 = 91;
+  a0.a91 = 92;
+  a0.a92 = 93;
+  a0.a93 = 94;
+  a0.a94 = 95;
+  a0.a95 = 96;
+  a0.a96 = 97;
+  a0.a97 = 98;
+  a0.a98 = 99;
+  a0.a99 = 100;
+  a0.a100 = 101;
+  a0.a101 = 102;
+  a0.a102 = 103;
+  a0.a103 = 104;
+  a0.a104 = 105;
+  a0.a105 = 106;
+  a0.a106 = 107;
+  a0.a107 = 108;
+  a0.a108 = 109;
+  a0.a109 = 110;
+  a0.a110 = 111;
+  a0.a111 = 112;
+  a0.a112 = 113;
+  a0.a113 = 114;
+  a0.a114 = 115;
+  a0.a115 = 116;
+  a0.a116 = 117;
+  a0.a117 = 118;
+  a0.a118 = 119;
+  a0.a119 = 120;
+  a0.a120 = 121;
+  a0.a121 = 122;
+  a0.a122 = 123;
+  a0.a123 = 124;
+  a0.a124 = 125;
+  a0.a125 = 126;
+  a0.a126 = 127;
+  a0.a127 = 128;
+
+  final result = passStruct1024BytesHomogeneousUint64(a0);
+
+  print("result = $result");
+
+  Expect.equals(8256, result);
+
+  free(a0.addressOf);
+}
+
+final passFloatStruct16BytesHomogeneousFloatFloatStruct1 =
+    ffiTestFunctions.lookupFunction<
+        Float Function(
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float),
+        double Function(
+            double,
+            Struct16BytesHomogeneousFloat,
+            double,
+            Struct16BytesHomogeneousFloat,
+            double,
+            Struct16BytesHomogeneousFloat,
+            double,
+            Struct16BytesHomogeneousFloat,
+            double)>("PassFloatStruct16BytesHomogeneousFloatFloatStruct1");
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+void testPassFloatStruct16BytesHomogeneousFloatFloatStruct1() {
+  double a0;
+  Struct16BytesHomogeneousFloat a1 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a2;
+  Struct16BytesHomogeneousFloat a3 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a4;
+  Struct16BytesHomogeneousFloat a5 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a6;
+  Struct16BytesHomogeneousFloat a7 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a8;
+
+  a0 = -1.0;
+  a1.a0 = 2.0;
+  a1.a1 = -3.0;
+  a1.a2 = 4.0;
+  a1.a3 = -5.0;
+  a2 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a3.a2 = -9.0;
+  a3.a3 = 10.0;
+  a4 = -11.0;
+  a5.a0 = 12.0;
+  a5.a1 = -13.0;
+  a5.a2 = 14.0;
+  a5.a3 = -15.0;
+  a6 = 16.0;
+  a7.a0 = -17.0;
+  a7.a1 = 18.0;
+  a7.a2 = -19.0;
+  a7.a3 = 20.0;
+  a8 = -21.0;
+
+  final result = passFloatStruct16BytesHomogeneousFloatFloatStruct1(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-11.0, result);
+
+  free(a1.addressOf);
+  free(a3.addressOf);
+  free(a5.addressOf);
+  free(a7.addressOf);
+}
+
+final passFloatStruct32BytesHomogeneousDoubleFloatStruct =
+    ffiTestFunctions.lookupFunction<
+        Double Function(
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float),
+        double Function(
+            double,
+            Struct32BytesHomogeneousDouble,
+            double,
+            Struct32BytesHomogeneousDouble,
+            double,
+            Struct32BytesHomogeneousDouble,
+            double,
+            Struct32BytesHomogeneousDouble,
+            double)>("PassFloatStruct32BytesHomogeneousDoubleFloatStruct");
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+void testPassFloatStruct32BytesHomogeneousDoubleFloatStruct() {
+  double a0;
+  Struct32BytesHomogeneousDouble a1 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a2;
+  Struct32BytesHomogeneousDouble a3 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a4;
+  Struct32BytesHomogeneousDouble a5 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a6;
+  Struct32BytesHomogeneousDouble a7 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a8;
+
+  a0 = -1.0;
+  a1.a0 = 2.0;
+  a1.a1 = -3.0;
+  a1.a2 = 4.0;
+  a1.a3 = -5.0;
+  a2 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a3.a2 = -9.0;
+  a3.a3 = 10.0;
+  a4 = -11.0;
+  a5.a0 = 12.0;
+  a5.a1 = -13.0;
+  a5.a2 = 14.0;
+  a5.a3 = -15.0;
+  a6 = 16.0;
+  a7.a0 = -17.0;
+  a7.a1 = 18.0;
+  a7.a2 = -19.0;
+  a7.a3 = 20.0;
+  a8 = -21.0;
+
+  final result = passFloatStruct32BytesHomogeneousDoubleFloatStruct(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-11.0, result);
+
+  free(a1.addressOf);
+  free(a3.addressOf);
+  free(a5.addressOf);
+  free(a7.addressOf);
+}
+
+final passInt8Struct16BytesMixedInt8Struct16BytesMixedIn =
+    ffiTestFunctions.lookupFunction<
+        Double Function(Int8, Struct16BytesMixed, Int8, Struct16BytesMixed,
+            Int8, Struct16BytesMixed, Int8, Struct16BytesMixed, Int8),
+        double Function(
+            int,
+            Struct16BytesMixed,
+            int,
+            Struct16BytesMixed,
+            int,
+            Struct16BytesMixed,
+            int,
+            Struct16BytesMixed,
+            int)>("PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn");
+
+/// Tests the alignment of structs in integers registers and on the stack.
+/// Arm32 aligns this struct at 8.
+/// Also, arm32 allocates the second struct partially in registers, partially
+/// on stack.
+/// Test backfilling of integer registers.
+void testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn() {
+  int a0;
+  Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
+  int a2;
+  Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
+  int a4;
+  Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+  int a6;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  int a8;
+
+  a0 = -1;
+  a1.a0 = 2.0;
+  a1.a1 = -3;
+  a2 = 4;
+  a3.a0 = -5.0;
+  a3.a1 = 6;
+  a4 = -7;
+  a5.a0 = 8.0;
+  a5.a1 = -9;
+  a6 = 10;
+  a7.a0 = -11.0;
+  a7.a1 = 12;
+  a8 = -13;
+
+  final result = passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-7.0, result);
+
+  free(a1.addressOf);
+  free(a3.addressOf);
+  free(a5.addressOf);
+  free(a7.addressOf);
+}
+
+final passDoublex6Struct16BytesMixedx4Int32 = ffiTestFunctions.lookupFunction<
+    Double Function(
+        Double,
+        Double,
+        Double,
+        Double,
+        Double,
+        Double,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Int32),
+    double Function(
+        double,
+        double,
+        double,
+        double,
+        double,
+        double,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        int)>("PassDoublex6Struct16BytesMixedx4Int32");
+
+/// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+/// structs. The rest of the structs will go on the stack.
+/// The int will be backfilled into the int register.
+void testPassDoublex6Struct16BytesMixedx4Int32() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+  double a5;
+  Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+  int a10;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+  a5 = 6.0;
+  a6.a0 = -7.0;
+  a6.a1 = 8;
+  a7.a0 = -9.0;
+  a7.a1 = 10;
+  a8.a0 = -11.0;
+  a8.a1 = 12;
+  a9.a0 = -13.0;
+  a9.a1 = 14;
+  a10 = -15;
+
+  final result = passDoublex6Struct16BytesMixedx4Int32(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+
+  print("result = $result");
+
+  Expect.approxEquals(-8.0, result);
+
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passInt32x4Struct16BytesMixedx4Double = ffiTestFunctions.lookupFunction<
+    Double Function(Int32, Int32, Int32, Int32, Struct16BytesMixed,
+        Struct16BytesMixed, Struct16BytesMixed, Struct16BytesMixed, Double),
+    double Function(
+        int,
+        int,
+        int,
+        int,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        double)>("PassInt32x4Struct16BytesMixedx4Double");
+
+/// On Linux x64, it will exhaust int registers first.
+/// The rest of the structs will go on the stack.
+/// The double will be backfilled into the xmm register.
+void testPassInt32x4Struct16BytesMixedx4Double() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  double a8;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4.a0 = -5.0;
+  a4.a1 = 6;
+  a5.a0 = -7.0;
+  a5.a1 = 8;
+  a6.a0 = -9.0;
+  a6.a1 = 10;
+  a7.a0 = -11.0;
+  a7.a1 = 12;
+  a8 = -13.0;
+
+  final result =
+      passInt32x4Struct16BytesMixedx4Double(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-7.0, result);
+
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+}
+
+final passStruct40BytesHomogeneousDoubleStruct4BytesHomo =
+    ffiTestFunctions.lookupFunction<
+            Double Function(Struct40BytesHomogeneousDouble,
+                Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat),
+            double Function(Struct40BytesHomogeneousDouble,
+                Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat)>(
+        "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo");
+
+/// On various architectures, first struct is allocated on stack.
+/// Check that the other two arguments are allocated on registers.
+void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
+  Struct40BytesHomogeneousDouble a0 =
+      allocate<Struct40BytesHomogeneousDouble>().ref;
+  Struct4BytesHomogeneousInt16 a1 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct8BytesHomogeneousFloat a2 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+  a1.a0 = 6;
+  a1.a1 = -7;
+  a2.a0 = 8.0;
+  a2.a1 = -9.0;
+
+  final result = passStruct40BytesHomogeneousDoubleStruct4BytesHomo(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.approxEquals(-5.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+}
+
+final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
+    Int64 Function(StructAlignmentInt16),
+    int Function(StructAlignmentInt16)>("PassStructAlignmentInt16");
+
+/// Test alignment and padding of 16 byte int within struct.
+void testPassStructAlignmentInt16() {
+  StructAlignmentInt16 a0 = allocate<StructAlignmentInt16>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  final result = passStructAlignmentInt16(a0);
+
+  print("result = $result");
+
+  Expect.equals(-2, result);
+
+  free(a0.addressOf);
+}
+
+final passStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
+    Int64 Function(StructAlignmentInt32),
+    int Function(StructAlignmentInt32)>("PassStructAlignmentInt32");
+
+/// Test alignment and padding of 32 byte int within struct.
+void testPassStructAlignmentInt32() {
+  StructAlignmentInt32 a0 = allocate<StructAlignmentInt32>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  final result = passStructAlignmentInt32(a0);
+
+  print("result = $result");
+
+  Expect.equals(-2, result);
+
+  free(a0.addressOf);
+}
+
+final passStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
+    Int64 Function(StructAlignmentInt64),
+    int Function(StructAlignmentInt64)>("PassStructAlignmentInt64");
+
+/// Test alignment and padding of 64 byte int within struct.
+void testPassStructAlignmentInt64() {
+  StructAlignmentInt64 a0 = allocate<StructAlignmentInt64>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  final result = passStructAlignmentInt64(a0);
+
+  print("result = $result");
+
+  Expect.equals(-2, result);
+
+  free(a0.addressOf);
+}
+
+final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
+    Struct1ByteInt Function(Int8),
+    Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
+
+/// Smallest struct with data.
+void testReturnStruct1ByteInt() {
+  int a0;
+
+  a0 = -1;
+
+  final result = returnStruct1ByteInt(a0);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+}
+
+final returnStruct3BytesInt = ffiTestFunctions.lookupFunction<
+    Struct3BytesInt Function(Int16, Int8),
+    Struct3BytesInt Function(int, int)>("ReturnStruct3BytesInt");
+
+/// Smaller than word size return value on all architectures.
+void testReturnStruct3BytesInt() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct3BytesInt(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct4BytesHomogeneousInt16 = ffiTestFunctions.lookupFunction<
+    Struct4BytesHomogeneousInt16 Function(Int16, Int16),
+    Struct4BytesHomogeneousInt16 Function(
+        int, int)>("ReturnStruct4BytesHomogeneousInt16");
+
+/// Word size return value on 32 bit architectures..
+void testReturnStruct4BytesHomogeneousInt16() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct4BytesHomogeneousInt16(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct7BytesInt = ffiTestFunctions.lookupFunction<
+    Struct7BytesInt Function(Int32, Int16, Int8),
+    Struct7BytesInt Function(int, int, int)>("ReturnStruct7BytesInt");
+
+/// Non-wordsize return value.
+void testReturnStruct7BytesInt() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct7BytesInt(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct8BytesInt = ffiTestFunctions.lookupFunction<
+    Struct8BytesInt Function(Int16, Int16, Int32),
+    Struct8BytesInt Function(int, int, int)>("ReturnStruct8BytesInt");
+
+/// Return value in integer registers on many architectures.
+void testReturnStruct8BytesInt() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct8BytesInt(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct8BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct8BytesHomogeneousFloat Function(Float, Float),
+    Struct8BytesHomogeneousFloat Function(
+        double, double)>("ReturnStruct8BytesHomogeneousFloat");
+
+/// Return value in FP registers on many architectures.
+void testReturnStruct8BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+
+  a0 = -1.0;
+  a1 = 2.0;
+
+  final result = returnStruct8BytesHomogeneousFloat(a0, a1);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+}
+
+final returnStruct8BytesMixed = ffiTestFunctions.lookupFunction<
+    Struct8BytesMixed Function(Float, Int16, Int16),
+    Struct8BytesMixed Function(double, int, int)>("ReturnStruct8BytesMixed");
+
+/// Return value split over FP and integer register in x64.
+void testReturnStruct8BytesMixed() {
+  double a0;
+  int a1;
+  int a2;
+
+  a0 = -1.0;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct8BytesMixed(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct9BytesInt = ffiTestFunctions.lookupFunction<
+    Struct9BytesInt Function(Int64, Int8),
+    Struct9BytesInt Function(int, int)>("ReturnStruct9BytesInt");
+
+/// Return value in two integer registers on x64.
+/// The second register only contains a single byte.
+void testReturnStruct9BytesInt() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct9BytesInt(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct9BytesHomogeneousUint82 = ffiTestFunctions.lookupFunction<
+    Struct9BytesHomogeneousUint82 Function(
+        Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
+    Struct9BytesHomogeneousUint82 Function(int, int, int, int, int, int, int,
+        int, int)>("ReturnStruct9BytesHomogeneousUint82");
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+void testReturnStruct9BytesHomogeneousUint82() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  int a8;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+
+  final result =
+      returnStruct9BytesHomogeneousUint82(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+  Expect.equals(a7, result.a7);
+  Expect.equals(a8, result.a8);
+}
+
+final returnStruct12BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct12BytesHomogeneousFloat Function(Float, Float, Float),
+    Struct12BytesHomogeneousFloat Function(
+        double, double, double)>("ReturnStruct12BytesHomogeneousFloat");
+
+/// Return value in FPU registers, but does not use all registers on arm hardfp
+/// and arm64.
+void testReturnStruct12BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+  double a2;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+
+  final result = returnStruct12BytesHomogeneousFloat(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+}
+
+final returnStruct16BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct16BytesHomogeneousFloat Function(Float, Float, Float, Float),
+    Struct16BytesHomogeneousFloat Function(
+        double, double, double, double)>("ReturnStruct16BytesHomogeneousFloat");
+
+/// Return value in FPU registers on arm hardfp and arm64.
+void testReturnStruct16BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+
+  final result = returnStruct16BytesHomogeneousFloat(a0, a1, a2, a3);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+}
+
+final returnStruct16BytesMixed = ffiTestFunctions.lookupFunction<
+    Struct16BytesMixed Function(Double, Int64),
+    Struct16BytesMixed Function(double, int)>("ReturnStruct16BytesMixed");
+
+/// Return value split over FP and integer register in x64.
+void testReturnStruct16BytesMixed() {
+  double a0;
+  int a1;
+
+  a0 = -1.0;
+  a1 = 2;
+
+  final result = returnStruct16BytesMixed(a0, a1);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct16BytesMixed2 = ffiTestFunctions.lookupFunction<
+    Struct16BytesMixed2 Function(Float, Float, Float, Int32),
+    Struct16BytesMixed2 Function(
+        double, double, double, int)>("ReturnStruct16BytesMixed2");
+
+/// Return value split over FP and integer register in x64.
+/// The integer register contains half float half int.
+void testReturnStruct16BytesMixed2() {
+  double a0;
+  double a1;
+  double a2;
+  int a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4;
+
+  final result = returnStruct16BytesMixed2(a0, a1, a2, a3);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+}
+
+final returnStruct17BytesInt = ffiTestFunctions.lookupFunction<
+    Struct17BytesInt Function(Int64, Int64, Int8),
+    Struct17BytesInt Function(int, int, int)>("ReturnStruct17BytesInt");
+
+/// Rerturn value returned in preallocated space passed by pointer on most ABIs.
+/// Is non word size on purpose, to test that structs are rounded up to word size
+/// on all ABIs.
+void testReturnStruct17BytesInt() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct17BytesInt(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct19BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct19BytesHomogeneousUint8 Function(
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8),
+    Struct19BytesHomogeneousUint8 Function(
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int)>("ReturnStruct19BytesHomogeneousUint8");
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+void testReturnStruct19BytesHomogeneousUint8() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  int a8;
+  int a9;
+  int a10;
+  int a11;
+  int a12;
+  int a13;
+  int a14;
+  int a15;
+  int a16;
+  int a17;
+  int a18;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+  a9 = 10;
+  a10 = 11;
+  a11 = 12;
+  a12 = 13;
+  a13 = 14;
+  a14 = 15;
+  a15 = 16;
+  a16 = 17;
+  a17 = 18;
+  a18 = 19;
+
+  final result = returnStruct19BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6,
+      a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+  Expect.equals(a7, result.a7);
+  Expect.equals(a8, result.a8);
+  Expect.equals(a9, result.a9);
+  Expect.equals(a10, result.a10);
+  Expect.equals(a11, result.a11);
+  Expect.equals(a12, result.a12);
+  Expect.equals(a13, result.a13);
+  Expect.equals(a14, result.a14);
+  Expect.equals(a15, result.a15);
+  Expect.equals(a16, result.a16);
+  Expect.equals(a17, result.a17);
+  Expect.equals(a18, result.a18);
+}
+
+final returnStruct20BytesHomogeneousInt32 = ffiTestFunctions.lookupFunction<
+    Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32, Int32),
+    Struct20BytesHomogeneousInt32 Function(
+        int, int, int, int, int)>("ReturnStruct20BytesHomogeneousInt32");
+
+/// Return value too big to go in cpu registers on arm64.
+void testReturnStruct20BytesHomogeneousInt32() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+
+  final result = returnStruct20BytesHomogeneousInt32(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+}
+
+final returnStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct20BytesHomogeneousFloat Function(Float, Float, Float, Float, Float),
+    Struct20BytesHomogeneousFloat Function(double, double, double, double,
+        double)>("ReturnStruct20BytesHomogeneousFloat");
+
+/// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
+void testReturnStruct20BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+
+  final result = returnStruct20BytesHomogeneousFloat(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+  Expect.approxEquals(a4, result.a4);
+}
+
+final returnStruct32BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
+    Struct32BytesHomogeneousDouble Function(Double, Double, Double, Double),
+    Struct32BytesHomogeneousDouble Function(double, double, double,
+        double)>("ReturnStruct32BytesHomogeneousDouble");
+
+/// Return value in FPU registers on arm64.
+void testReturnStruct32BytesHomogeneousDouble() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+
+  final result = returnStruct32BytesHomogeneousDouble(a0, a1, a2, a3);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+}
+
+final returnStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
+    Struct40BytesHomogeneousDouble Function(
+        Double, Double, Double, Double, Double),
+    Struct40BytesHomogeneousDouble Function(double, double, double, double,
+        double)>("ReturnStruct40BytesHomogeneousDouble");
+
+/// Return value too big to go in FPU registers on arm64.
+void testReturnStruct40BytesHomogeneousDouble() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+
+  final result = returnStruct40BytesHomogeneousDouble(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+  Expect.approxEquals(a4, result.a4);
+}
+
+final returnStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
+    Struct1024BytesHomogeneousUint64 Function(
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64),
+    Struct1024BytesHomogeneousUint64 Function(
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int)>("ReturnStruct1024BytesHomogeneousUint64");
+
+/// Test 1kb struct.
+void testReturnStruct1024BytesHomogeneousUint64() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  int a8;
+  int a9;
+  int a10;
+  int a11;
+  int a12;
+  int a13;
+  int a14;
+  int a15;
+  int a16;
+  int a17;
+  int a18;
+  int a19;
+  int a20;
+  int a21;
+  int a22;
+  int a23;
+  int a24;
+  int a25;
+  int a26;
+  int a27;
+  int a28;
+  int a29;
+  int a30;
+  int a31;
+  int a32;
+  int a33;
+  int a34;
+  int a35;
+  int a36;
+  int a37;
+  int a38;
+  int a39;
+  int a40;
+  int a41;
+  int a42;
+  int a43;
+  int a44;
+  int a45;
+  int a46;
+  int a47;
+  int a48;
+  int a49;
+  int a50;
+  int a51;
+  int a52;
+  int a53;
+  int a54;
+  int a55;
+  int a56;
+  int a57;
+  int a58;
+  int a59;
+  int a60;
+  int a61;
+  int a62;
+  int a63;
+  int a64;
+  int a65;
+  int a66;
+  int a67;
+  int a68;
+  int a69;
+  int a70;
+  int a71;
+  int a72;
+  int a73;
+  int a74;
+  int a75;
+  int a76;
+  int a77;
+  int a78;
+  int a79;
+  int a80;
+  int a81;
+  int a82;
+  int a83;
+  int a84;
+  int a85;
+  int a86;
+  int a87;
+  int a88;
+  int a89;
+  int a90;
+  int a91;
+  int a92;
+  int a93;
+  int a94;
+  int a95;
+  int a96;
+  int a97;
+  int a98;
+  int a99;
+  int a100;
+  int a101;
+  int a102;
+  int a103;
+  int a104;
+  int a105;
+  int a106;
+  int a107;
+  int a108;
+  int a109;
+  int a110;
+  int a111;
+  int a112;
+  int a113;
+  int a114;
+  int a115;
+  int a116;
+  int a117;
+  int a118;
+  int a119;
+  int a120;
+  int a121;
+  int a122;
+  int a123;
+  int a124;
+  int a125;
+  int a126;
+  int a127;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+  a9 = 10;
+  a10 = 11;
+  a11 = 12;
+  a12 = 13;
+  a13 = 14;
+  a14 = 15;
+  a15 = 16;
+  a16 = 17;
+  a17 = 18;
+  a18 = 19;
+  a19 = 20;
+  a20 = 21;
+  a21 = 22;
+  a22 = 23;
+  a23 = 24;
+  a24 = 25;
+  a25 = 26;
+  a26 = 27;
+  a27 = 28;
+  a28 = 29;
+  a29 = 30;
+  a30 = 31;
+  a31 = 32;
+  a32 = 33;
+  a33 = 34;
+  a34 = 35;
+  a35 = 36;
+  a36 = 37;
+  a37 = 38;
+  a38 = 39;
+  a39 = 40;
+  a40 = 41;
+  a41 = 42;
+  a42 = 43;
+  a43 = 44;
+  a44 = 45;
+  a45 = 46;
+  a46 = 47;
+  a47 = 48;
+  a48 = 49;
+  a49 = 50;
+  a50 = 51;
+  a51 = 52;
+  a52 = 53;
+  a53 = 54;
+  a54 = 55;
+  a55 = 56;
+  a56 = 57;
+  a57 = 58;
+  a58 = 59;
+  a59 = 60;
+  a60 = 61;
+  a61 = 62;
+  a62 = 63;
+  a63 = 64;
+  a64 = 65;
+  a65 = 66;
+  a66 = 67;
+  a67 = 68;
+  a68 = 69;
+  a69 = 70;
+  a70 = 71;
+  a71 = 72;
+  a72 = 73;
+  a73 = 74;
+  a74 = 75;
+  a75 = 76;
+  a76 = 77;
+  a77 = 78;
+  a78 = 79;
+  a79 = 80;
+  a80 = 81;
+  a81 = 82;
+  a82 = 83;
+  a83 = 84;
+  a84 = 85;
+  a85 = 86;
+  a86 = 87;
+  a87 = 88;
+  a88 = 89;
+  a89 = 90;
+  a90 = 91;
+  a91 = 92;
+  a92 = 93;
+  a93 = 94;
+  a94 = 95;
+  a95 = 96;
+  a96 = 97;
+  a97 = 98;
+  a98 = 99;
+  a99 = 100;
+  a100 = 101;
+  a101 = 102;
+  a102 = 103;
+  a103 = 104;
+  a104 = 105;
+  a105 = 106;
+  a106 = 107;
+  a107 = 108;
+  a108 = 109;
+  a109 = 110;
+  a110 = 111;
+  a111 = 112;
+  a112 = 113;
+  a113 = 114;
+  a114 = 115;
+  a115 = 116;
+  a116 = 117;
+  a117 = 118;
+  a118 = 119;
+  a119 = 120;
+  a120 = 121;
+  a121 = 122;
+  a122 = 123;
+  a123 = 124;
+  a124 = 125;
+  a125 = 126;
+  a126 = 127;
+  a127 = 128;
+
+  final result = returnStruct1024BytesHomogeneousUint64(
+      a0,
+      a1,
+      a2,
+      a3,
+      a4,
+      a5,
+      a6,
+      a7,
+      a8,
+      a9,
+      a10,
+      a11,
+      a12,
+      a13,
+      a14,
+      a15,
+      a16,
+      a17,
+      a18,
+      a19,
+      a20,
+      a21,
+      a22,
+      a23,
+      a24,
+      a25,
+      a26,
+      a27,
+      a28,
+      a29,
+      a30,
+      a31,
+      a32,
+      a33,
+      a34,
+      a35,
+      a36,
+      a37,
+      a38,
+      a39,
+      a40,
+      a41,
+      a42,
+      a43,
+      a44,
+      a45,
+      a46,
+      a47,
+      a48,
+      a49,
+      a50,
+      a51,
+      a52,
+      a53,
+      a54,
+      a55,
+      a56,
+      a57,
+      a58,
+      a59,
+      a60,
+      a61,
+      a62,
+      a63,
+      a64,
+      a65,
+      a66,
+      a67,
+      a68,
+      a69,
+      a70,
+      a71,
+      a72,
+      a73,
+      a74,
+      a75,
+      a76,
+      a77,
+      a78,
+      a79,
+      a80,
+      a81,
+      a82,
+      a83,
+      a84,
+      a85,
+      a86,
+      a87,
+      a88,
+      a89,
+      a90,
+      a91,
+      a92,
+      a93,
+      a94,
+      a95,
+      a96,
+      a97,
+      a98,
+      a99,
+      a100,
+      a101,
+      a102,
+      a103,
+      a104,
+      a105,
+      a106,
+      a107,
+      a108,
+      a109,
+      a110,
+      a111,
+      a112,
+      a113,
+      a114,
+      a115,
+      a116,
+      a117,
+      a118,
+      a119,
+      a120,
+      a121,
+      a122,
+      a123,
+      a124,
+      a125,
+      a126,
+      a127);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+  Expect.equals(a7, result.a7);
+  Expect.equals(a8, result.a8);
+  Expect.equals(a9, result.a9);
+  Expect.equals(a10, result.a10);
+  Expect.equals(a11, result.a11);
+  Expect.equals(a12, result.a12);
+  Expect.equals(a13, result.a13);
+  Expect.equals(a14, result.a14);
+  Expect.equals(a15, result.a15);
+  Expect.equals(a16, result.a16);
+  Expect.equals(a17, result.a17);
+  Expect.equals(a18, result.a18);
+  Expect.equals(a19, result.a19);
+  Expect.equals(a20, result.a20);
+  Expect.equals(a21, result.a21);
+  Expect.equals(a22, result.a22);
+  Expect.equals(a23, result.a23);
+  Expect.equals(a24, result.a24);
+  Expect.equals(a25, result.a25);
+  Expect.equals(a26, result.a26);
+  Expect.equals(a27, result.a27);
+  Expect.equals(a28, result.a28);
+  Expect.equals(a29, result.a29);
+  Expect.equals(a30, result.a30);
+  Expect.equals(a31, result.a31);
+  Expect.equals(a32, result.a32);
+  Expect.equals(a33, result.a33);
+  Expect.equals(a34, result.a34);
+  Expect.equals(a35, result.a35);
+  Expect.equals(a36, result.a36);
+  Expect.equals(a37, result.a37);
+  Expect.equals(a38, result.a38);
+  Expect.equals(a39, result.a39);
+  Expect.equals(a40, result.a40);
+  Expect.equals(a41, result.a41);
+  Expect.equals(a42, result.a42);
+  Expect.equals(a43, result.a43);
+  Expect.equals(a44, result.a44);
+  Expect.equals(a45, result.a45);
+  Expect.equals(a46, result.a46);
+  Expect.equals(a47, result.a47);
+  Expect.equals(a48, result.a48);
+  Expect.equals(a49, result.a49);
+  Expect.equals(a50, result.a50);
+  Expect.equals(a51, result.a51);
+  Expect.equals(a52, result.a52);
+  Expect.equals(a53, result.a53);
+  Expect.equals(a54, result.a54);
+  Expect.equals(a55, result.a55);
+  Expect.equals(a56, result.a56);
+  Expect.equals(a57, result.a57);
+  Expect.equals(a58, result.a58);
+  Expect.equals(a59, result.a59);
+  Expect.equals(a60, result.a60);
+  Expect.equals(a61, result.a61);
+  Expect.equals(a62, result.a62);
+  Expect.equals(a63, result.a63);
+  Expect.equals(a64, result.a64);
+  Expect.equals(a65, result.a65);
+  Expect.equals(a66, result.a66);
+  Expect.equals(a67, result.a67);
+  Expect.equals(a68, result.a68);
+  Expect.equals(a69, result.a69);
+  Expect.equals(a70, result.a70);
+  Expect.equals(a71, result.a71);
+  Expect.equals(a72, result.a72);
+  Expect.equals(a73, result.a73);
+  Expect.equals(a74, result.a74);
+  Expect.equals(a75, result.a75);
+  Expect.equals(a76, result.a76);
+  Expect.equals(a77, result.a77);
+  Expect.equals(a78, result.a78);
+  Expect.equals(a79, result.a79);
+  Expect.equals(a80, result.a80);
+  Expect.equals(a81, result.a81);
+  Expect.equals(a82, result.a82);
+  Expect.equals(a83, result.a83);
+  Expect.equals(a84, result.a84);
+  Expect.equals(a85, result.a85);
+  Expect.equals(a86, result.a86);
+  Expect.equals(a87, result.a87);
+  Expect.equals(a88, result.a88);
+  Expect.equals(a89, result.a89);
+  Expect.equals(a90, result.a90);
+  Expect.equals(a91, result.a91);
+  Expect.equals(a92, result.a92);
+  Expect.equals(a93, result.a93);
+  Expect.equals(a94, result.a94);
+  Expect.equals(a95, result.a95);
+  Expect.equals(a96, result.a96);
+  Expect.equals(a97, result.a97);
+  Expect.equals(a98, result.a98);
+  Expect.equals(a99, result.a99);
+  Expect.equals(a100, result.a100);
+  Expect.equals(a101, result.a101);
+  Expect.equals(a102, result.a102);
+  Expect.equals(a103, result.a103);
+  Expect.equals(a104, result.a104);
+  Expect.equals(a105, result.a105);
+  Expect.equals(a106, result.a106);
+  Expect.equals(a107, result.a107);
+  Expect.equals(a108, result.a108);
+  Expect.equals(a109, result.a109);
+  Expect.equals(a110, result.a110);
+  Expect.equals(a111, result.a111);
+  Expect.equals(a112, result.a112);
+  Expect.equals(a113, result.a113);
+  Expect.equals(a114, result.a114);
+  Expect.equals(a115, result.a115);
+  Expect.equals(a116, result.a116);
+  Expect.equals(a117, result.a117);
+  Expect.equals(a118, result.a118);
+  Expect.equals(a119, result.a119);
+  Expect.equals(a120, result.a120);
+  Expect.equals(a121, result.a121);
+  Expect.equals(a122, result.a122);
+  Expect.equals(a123, result.a123);
+  Expect.equals(a124, result.a124);
+  Expect.equals(a125, result.a125);
+  Expect.equals(a126, result.a126);
+  Expect.equals(a127, result.a127);
+}
+
+final returnStructArgumentStruct1ByteInt = ffiTestFunctions.lookupFunction<
+    Struct1ByteInt Function(Struct1ByteInt),
+    Struct1ByteInt Function(
+        Struct1ByteInt)>("ReturnStructArgumentStruct1ByteInt");
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in int registers in most ABIs.
+void testReturnStructArgumentStruct1ByteInt() {
+  Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
+
+  a0.a0 = -1;
+
+  final result = returnStructArgumentStruct1ByteInt(a0);
+
+  print("result = $result");
+
+  Expect.equals(a0.a0, result.a0);
+
+  free(a0.addressOf);
+}
+
+final returnStructArgumentInt32x8Struct1ByteInt =
+    ffiTestFunctions.lookupFunction<
+        Struct1ByteInt Function(Int32, Int32, Int32, Int32, Int32, Int32, Int32,
+            Int32, Struct1ByteInt),
+        Struct1ByteInt Function(int, int, int, int, int, int, int, int,
+            Struct1ByteInt)>("ReturnStructArgumentInt32x8Struct1ByteInt");
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed on stack on all ABIs.
+void testReturnStructArgumentInt32x8Struct1ByteInt() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+  a5 = 6;
+  a6 = -7;
+  a7 = 8;
+  a8.a0 = -9;
+
+  final result = returnStructArgumentInt32x8Struct1ByteInt(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.equals(a8.a0, result.a0);
+
+  free(a8.addressOf);
+}
+
+final returnStructArgumentStruct8BytesHomogeneousFloat =
+    ffiTestFunctions.lookupFunction<
+            Struct8BytesHomogeneousFloat Function(Struct8BytesHomogeneousFloat),
+            Struct8BytesHomogeneousFloat Function(
+                Struct8BytesHomogeneousFloat)>(
+        "ReturnStructArgumentStruct8BytesHomogeneousFloat");
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in float registers in most ABIs.
+void testReturnStructArgumentStruct8BytesHomogeneousFloat() {
+  Struct8BytesHomogeneousFloat a0 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+
+  final result = returnStructArgumentStruct8BytesHomogeneousFloat(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0.a0, result.a0);
+  Expect.approxEquals(a0.a1, result.a1);
+
+  free(a0.addressOf);
+}
+
+final returnStructArgumentStruct20BytesHomogeneousInt32 =
+    ffiTestFunctions
+        .lookupFunction<
+                Struct20BytesHomogeneousInt32 Function(
+                    Struct20BytesHomogeneousInt32),
+                Struct20BytesHomogeneousInt32 Function(
+                    Struct20BytesHomogeneousInt32)>(
+            "ReturnStructArgumentStruct20BytesHomogeneousInt32");
+
+/// On arm64, both argument and return value are passed in by pointer.
+void testReturnStructArgumentStruct20BytesHomogeneousInt32() {
+  Struct20BytesHomogeneousInt32 a0 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a0.a3 = 4;
+  a0.a4 = -5;
+
+  final result = returnStructArgumentStruct20BytesHomogeneousInt32(a0);
+
+  print("result = $result");
+
+  Expect.equals(a0.a0, result.a0);
+  Expect.equals(a0.a1, result.a1);
+  Expect.equals(a0.a2, result.a2);
+  Expect.equals(a0.a3, result.a3);
+  Expect.equals(a0.a4, result.a4);
+
+  free(a0.addressOf);
+}
+
+final returnStructArgumentInt32x8Struct20BytesHomogeneou =
+    ffiTestFunctions.lookupFunction<
+            Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32,
+                Int32, Int32, Int32, Int32, Struct20BytesHomogeneousInt32),
+            Struct20BytesHomogeneousInt32 Function(int, int, int, int, int, int,
+                int, int, Struct20BytesHomogeneousInt32)>(
+        "ReturnStructArgumentInt32x8Struct20BytesHomogeneou");
+
+/// On arm64, both argument and return value are passed in by pointer.
+/// Ints exhaust registers, so that pointer is passed on stack.
+void testReturnStructArgumentInt32x8Struct20BytesHomogeneou() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  Struct20BytesHomogeneousInt32 a8 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+  a5 = 6;
+  a6 = -7;
+  a7 = 8;
+  a8.a0 = -9;
+  a8.a1 = 10;
+  a8.a2 = -11;
+  a8.a3 = 12;
+  a8.a4 = -13;
+
+  final result = returnStructArgumentInt32x8Struct20BytesHomogeneou(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.equals(a8.a0, result.a0);
+  Expect.equals(a8.a1, result.a1);
+  Expect.equals(a8.a2, result.a2);
+  Expect.equals(a8.a3, result.a3);
+  Expect.equals(a8.a4, result.a4);
+
+  free(a8.addressOf);
+}
+
+final returnStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
+    StructAlignmentInt16 Function(Int8, Int16, Int8),
+    StructAlignmentInt16 Function(int, int, int)>("ReturnStructAlignmentInt16");
+
+/// Test alignment and padding of 16 byte int within struct.
+void testReturnStructAlignmentInt16() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStructAlignmentInt16(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
+    StructAlignmentInt32 Function(Int8, Int32, Int8),
+    StructAlignmentInt32 Function(int, int, int)>("ReturnStructAlignmentInt32");
+
+/// Test alignment and padding of 32 byte int within struct.
+void testReturnStructAlignmentInt32() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStructAlignmentInt32(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
+    StructAlignmentInt64 Function(Int8, Int64, Int8),
+    StructAlignmentInt64 Function(int, int, int)>("ReturnStructAlignmentInt64");
+
+/// Test alignment and padding of 64 byte int within struct.
+void testReturnStructAlignmentInt64() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStructAlignmentInt64(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
diff --git a/tests/ffi/generator/c_types.dart b/tests/ffi/generator/c_types.dart
new file mode 100644
index 0000000..f2948fa
--- /dev/null
+++ b/tests/ffi/generator/c_types.dart
@@ -0,0 +1,299 @@
+// Copyright (c) 2020, 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.
+
+import 'utils.dart';
+
+const int8 = FundamentalType(PrimitiveType.int8);
+const int16 = FundamentalType(PrimitiveType.int16);
+const int32 = FundamentalType(PrimitiveType.int32);
+const int64 = FundamentalType(PrimitiveType.int64);
+const uint8 = FundamentalType(PrimitiveType.uint8);
+const uint16 = FundamentalType(PrimitiveType.uint16);
+const uint32 = FundamentalType(PrimitiveType.uint32);
+const uint64 = FundamentalType(PrimitiveType.uint64);
+const intptr = FundamentalType(PrimitiveType.intptr);
+const float = FundamentalType(PrimitiveType.float);
+const double_ = FundamentalType(PrimitiveType.double_);
+
+enum PrimitiveType {
+  int8,
+  int16,
+  int32,
+  int64,
+  uint8,
+  uint16,
+  uint32,
+  uint64,
+  intptr,
+  float,
+  double_,
+}
+
+const primitiveNames = [
+  "int8",
+  "int16",
+  "int32",
+  "int64",
+  "uint8",
+  "uint16",
+  "uint32",
+  "uint64",
+  "intptr",
+  "float",
+  "double",
+];
+
+const intptrSize = -1;
+const primitiveSizesInBytes = [1, 2, 4, 8, 1, 2, 4, 8, intptrSize, 4, 8];
+
+abstract class CType {
+  String get cType;
+  String get dartCType;
+  String get dartType;
+  String get dartStructFieldAnnotation;
+
+  /// Has a known [size] that is the same for all architectures.
+  bool get hasSize;
+
+  /// Get a size in bytes that is the same on all architectures.
+  int get size;
+
+  String toString() => dartCType;
+
+  const CType();
+}
+
+class FundamentalType extends CType {
+  final PrimitiveType primitive;
+
+  const FundamentalType(this.primitive);
+
+  bool get isFloatingPoint =>
+      primitive == PrimitiveType.float || primitive == PrimitiveType.double_;
+  bool get isInteger => !isFloatingPoint;
+  bool get isUnsigned =>
+      primitive == PrimitiveType.uint8 ||
+      primitive == PrimitiveType.uint16 ||
+      primitive == PrimitiveType.uint32 ||
+      primitive == PrimitiveType.uint64;
+  bool get isSigned => !isUnsigned;
+
+  String get name => primitiveNames[primitive.index];
+
+  String get cType => "${name}${isInteger ? "_t" : ""}";
+  String get dartCType => name.upperCaseFirst();
+  String get dartType => isInteger ? "int" : "double";
+  String get dartStructFieldAnnotation => "@${dartCType}()";
+  bool get hasSize => primitive != PrimitiveType.intptr;
+  int get size {
+    if (!hasSize) {
+      throw "Size unknown.";
+    }
+    return primitiveSizesInBytes[primitive.index];
+  }
+}
+
+class PointerType extends CType {
+  final CType pointerTo;
+
+  PointerType(this.pointerTo);
+
+  String get cType => "${pointerTo.cType}*";
+  String get dartCType => "Pointer<${pointerTo.dartCType}>";
+  String get dartType => "Pointer<${pointerTo.dartType}>";
+  String get dartStructFieldAnnotation => "";
+  bool get hasSize => false;
+  int get size => throw "Size unknown";
+}
+
+/// Used to give [StructType] fields and [FunctionType] arguments names.
+class Member {
+  final CType type;
+  final String name;
+
+  Member(this.type, this.name);
+
+  String dartStructField(bool nnbd) {
+    final modifier = nnbd ? "external" : "";
+    return "${type.dartStructFieldAnnotation} $modifier ${type.dartType} $name;";
+  }
+
+  String get cStructField => "${type.cType} $name;";
+
+  String toString() => "$type $name";
+}
+
+List<Member> generateMemberNames(List<CType> memberTypes) {
+  int index = 0;
+  List<Member> result = [];
+  for (final type in memberTypes) {
+    result.add(Member(type, "a$index"));
+    index++;
+  }
+  return result;
+}
+
+class StructType extends CType {
+  final List<Member> members;
+
+  /// To disambiguate same size structs.
+  final String suffix;
+
+  StructType(List<CType> memberTypes)
+      : this.members = generateMemberNames(memberTypes),
+        this.suffix = "";
+  StructType.disambiguate(List<CType> memberTypes, this.suffix)
+      : this.members = generateMemberNames(memberTypes);
+
+  List<CType> get memberTypes => members.map((a) => a.type).toList();
+
+  String get cType => name;
+  String get dartCType => name;
+  String get dartType => name;
+  String get dartStructFieldAnnotation => "";
+
+  bool get hasSize =>
+      !memberTypes.map((e) => e.hasSize).contains(false) && !hasPadding;
+  int get size => memberTypes.fold(0, (int acc, e) => acc + e.size);
+
+  /// Rough approximation, to not redo all ABI logic here.
+  bool get hasPadding =>
+      members.length < 2 ? false : members[0].type.size < members[1].type.size;
+
+  bool get hasNestedStructs =>
+      members.map((e) => e.type is StructType).contains(true);
+
+  /// All members have the same type.
+  bool get isHomogeneous => memberTypes.toSet().length == 1;
+
+  /// All members have a floating point type.
+  bool get isOnlyFloatingPoint => !memberTypes.map((e) {
+        if (e is FundamentalType) {
+          return e.isFloatingPoint;
+        }
+        if (e is StructType) {
+          return e.isOnlyFloatingPoint;
+        }
+      }).contains(false);
+
+  /// All members have a integer type.
+  bool get isOnlyInteger => !memberTypes.map((e) {
+        if (e is FundamentalType) {
+          return e.isInteger;
+        }
+        if (e is StructType) {
+          return e.isOnlyInteger;
+        }
+      }).contains(false);
+
+  bool get isMixed => !isOnlyInteger && !isOnlyFloatingPoint;
+
+  String get name {
+    String result = "Struct";
+    if (hasSize) {
+      result += "${size}Byte" + (size != 1 ? "s" : "");
+    }
+    if (hasNestedStructs) {
+      result += "Nested";
+    }
+    if (members.length == 0) {
+      // No suffix.
+    } else if (hasPadding) {
+      result += "Alignment${memberTypes[1].dartCType}";
+    } else if (isHomogeneous && members.length > 1 && !hasNestedStructs) {
+      result += "Homogeneous${memberTypes.first.dartCType}";
+    } else if (isOnlyFloatingPoint) {
+      result += "Float";
+    } else if (isOnlyInteger) {
+      result += "Int";
+    } else {
+      result += "Mixed";
+    }
+    result += suffix;
+    return result;
+  }
+}
+
+class FunctionType extends CType {
+  final List<Member> arguments;
+  final CType returnValue;
+  final String reason;
+
+  List<CType> get argumentTypes => arguments.map((a) => a.type).toList();
+
+  FunctionType(List<CType> argumentTypes, this.returnValue, this.reason)
+      : this.arguments = generateMemberNames(argumentTypes);
+
+  String get cType =>
+      throw "Are not represented without function or variable name in C.";
+
+  String get dartCType {
+    final argumentsDartCType = argumentTypes.map((e) => e.dartCType).join(", ");
+    return "${returnValue.dartCType} Function($argumentsDartCType)";
+  }
+
+  String get dartType {
+    final argumentsDartType = argumentTypes.map((e) => e.dartType).join(", ");
+    return "${returnValue.dartType} Function($argumentsDartType)";
+  }
+
+  String get dartStructFieldAnnotation => throw "No nested function pointers.";
+
+  bool get hasSize => false;
+  int get size => throw "Unknown size.";
+
+  /// Group consecutive [arguments] by same type.
+  ///
+  /// Used for naming.
+  List<List<Member>> get argumentsGrouped {
+    List<List<Member>> result = [];
+    for (final a in arguments) {
+      if (result.isEmpty) {
+        result.add([a]);
+      } else if (result.last.first.type.dartCType == a.type.dartCType) {
+        result.last.add(a);
+      } else {
+        result.add([a]);
+      }
+    }
+    return result;
+  }
+
+  /// A suitable name based on the signature.
+  String get cName {
+    String result = "";
+    if (arguments.containsStructs && returnValue is FundamentalType) {
+      result = "Pass";
+    } else if (returnValue is StructType &&
+        argumentTypes.contains(returnValue)) {
+      result = "ReturnStructArgument";
+    } else if (returnValue is StructType) {
+      if (arguments.length == (returnValue as StructType).members.length) {
+        return "Return${returnValue.dartCType}";
+      }
+    } else {
+      result = "Uncategorized";
+    }
+
+    for (final group in argumentsGrouped) {
+      result += group.first.type.dartCType;
+      if (group.length > 1) {
+        result += "x${group.length}";
+      }
+    }
+    return result.limitTo(50);
+  }
+
+  String get dartTestName => "test$cName";
+
+  String get dartName => cName.lowerCaseFirst();
+
+  /// Only valid for [TestType.structReturnArgument].
+  Member get structReturnArgument =>
+      arguments.firstWhere((a) => a.type == returnValue);
+}
+
+extension MemberList on List<Member> {
+  bool get containsStructs => map((m) => m.type is StructType).contains(true);
+}
diff --git a/tests/ffi/generator/structs_by_value_tests_confguration.dart b/tests/ffi/generator/structs_by_value_tests_confguration.dart
new file mode 100644
index 0000000..487a68e
--- /dev/null
+++ b/tests/ffi/generator/structs_by_value_tests_confguration.dart
@@ -0,0 +1,373 @@
+// Copyright (c) 2020, 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.
+
+import 'c_types.dart';
+
+final functions = [
+  FunctionType(List.filled(10, struct1byteInt), int64, """
+Smallest struct with data.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct3bytesInt), int64, """
+Not a multiple of word size, not a power of two.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct4bytesInt), int64, """
+Exactly word size on 32-bit architectures.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct7bytesInt), int64, """
+Sub word size on 64 bit architectures.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct8bytesInt), int64, """
+Exactly word size struct on 64bit architectures.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct8bytesFloat), float, """
+Arguments passed in FP registers as long as they fit.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct8BytesMixed), float, """
+On x64, arguments go in int registers because it is not only float.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct9bytesInt), int64, """
+Argument is a single byte over a multiple of word size.
+10 struct arguments will exhaust available registers.
+Tests upper bytes in the integer registers that are partly filled.
+Tests stack alignment of non word size stack arguments."""),
+  FunctionType(List.filled(10, struct9bytesInt2), int64, """
+Argument is a single byte over a multiple of word size.
+10 struct arguments will exhaust available registers.
+Struct only has 1-byte aligned fields to test struct alignment itself.
+"""),
+  FunctionType(List.filled(6, struct12bytesFloat), float, """
+Arguments in FPU registers on arm hardfp and arm64.
+Struct arguments will exhaust available registers, and leave some empty.
+The last argument is to test whether arguments are backfilled."""),
+  FunctionType(List.filled(5, struct16bytesFloat), float, """
+On Linux x64 argument is transferred on stack because it is over 16 bytes.
+Arguments in FPU registers on arm hardfp and arm64.
+5 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct16bytesMixed), double_, """
+On x64, arguments are split over FP and int registers.
+On x64, it will exhaust the integer registers with the 6th argument.
+The rest goes on the stack.
+On arm, arguments are 8 byte aligned."""),
+  FunctionType(List.filled(10, struct16bytesMixed2), float, """
+On x64, arguments are split over FP and int registers.
+On x64, it will exhaust the integer registers with the 6th argument.
+The rest goes on the stack.
+On arm, arguments are 4 byte aligned."""),
+  FunctionType(List.filled(10, struct17bytesInt), int64, """
+Arguments are passed as pointer to copy on arm64.
+Tests that the memory allocated for copies are rounded up to word size."""),
+  FunctionType(List.filled(10, struct19bytesInt), int64, """
+The minimum alignment of this struct is only 1 byte based on its fields.
+Test that the memory backing these structs is extended to the right size.
+"""),
+  FunctionType(List.filled(10, struct20bytesInt), int32, """
+Argument too big to go into integer registers on arm64.
+The arguments are passed as pointers to copies.
+The amount of arguments exhausts the number of integer registers, such that
+pointers to copies are also passed on the stack."""),
+  FunctionType(
+      [struct20bytesFloat],
+      float,
+      """
+Argument too big to go into FPU registers in hardfp and arm64."""),
+  FunctionType(List.filled(5, struct32bytesDouble), double_, """
+Arguments in FPU registers on arm64.
+5 struct arguments will exhaust available registers."""),
+  FunctionType(
+      [struct40bytesDouble],
+      double_,
+      """
+Argument too big to go into FPU registers in arm64."""),
+  FunctionType(
+      [struct1024bytesInt],
+      uint64,
+      """
+Test 1kb struct."""),
+  FunctionType(
+      [
+        float,
+        struct16bytesFloat,
+        float,
+        struct16bytesFloat,
+        float,
+        struct16bytesFloat,
+        float,
+        struct16bytesFloat,
+        float
+      ],
+      float,
+      """
+Tests the alignment of structs in FPU registers and backfilling."""),
+  FunctionType(
+      [
+        float,
+        struct32bytesDouble,
+        float,
+        struct32bytesDouble,
+        float,
+        struct32bytesDouble,
+        float,
+        struct32bytesDouble,
+        float
+      ],
+      double_,
+      """
+Tests the alignment of structs in FPU registers and backfilling."""),
+  FunctionType(
+      [
+        int8,
+        struct16bytesMixed,
+        int8,
+        struct16bytesMixed,
+        int8,
+        struct16bytesMixed,
+        int8,
+        struct16bytesMixed,
+        int8
+      ],
+      double_,
+      """
+Tests the alignment of structs in integers registers and on the stack.
+Arm32 aligns this struct at 8.
+Also, arm32 allocates the second struct partially in registers, partially
+on stack.
+Test backfilling of integer registers."""),
+  FunctionType(
+      [
+        double_,
+        double_,
+        double_,
+        double_,
+        double_,
+        double_,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        int32,
+      ],
+      double_,
+      """
+On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+structs. The rest of the structs will go on the stack.
+The int will be backfilled into the int register."""),
+  FunctionType(
+      [
+        int32,
+        int32,
+        int32,
+        int32,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        double_,
+      ],
+      double_,
+      """
+On Linux x64, it will exhaust int registers first.
+The rest of the structs will go on the stack.
+The double will be backfilled into the xmm register."""),
+  FunctionType(
+      [
+        struct40bytesDouble,
+        struct4bytesInt,
+        struct8bytesFloat,
+      ],
+      double_,
+      """
+On various architectures, first struct is allocated on stack.
+Check that the other two arguments are allocated on registers."""),
+  FunctionType(
+      [structAlignmentInt16],
+      int64,
+      """
+Test alignment and padding of 16 byte int within struct."""),
+  FunctionType(
+      [structAlignmentInt32],
+      int64,
+      """
+Test alignment and padding of 32 byte int within struct."""),
+  FunctionType(
+      [structAlignmentInt64],
+      int64,
+      """
+Test alignment and padding of 64 byte int within struct."""),
+  FunctionType(struct1byteInt.memberTypes, struct1byteInt, """
+Smallest struct with data."""),
+  FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
+Smaller than word size return value on all architectures."""),
+  FunctionType(struct4bytesInt.memberTypes, struct4bytesInt, """
+Word size return value on 32 bit architectures.."""),
+  FunctionType(struct7bytesInt.memberTypes, struct7bytesInt, """
+Non-wordsize return value."""),
+  FunctionType(struct8bytesInt.memberTypes, struct8bytesInt, """
+Return value in integer registers on many architectures."""),
+  FunctionType(struct8bytesFloat.memberTypes, struct8bytesFloat, """
+Return value in FP registers on many architectures."""),
+  FunctionType(struct8BytesMixed.memberTypes, struct8BytesMixed, """
+Return value split over FP and integer register in x64."""),
+  FunctionType(struct9bytesInt.memberTypes, struct9bytesInt, """
+Return value in two integer registers on x64.
+The second register only contains a single byte."""),
+  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
+The minimum alignment of this struct is only 1 byte based on its fields.
+Test that the memory backing these structs is the right size and that
+dart:ffi trampolines do not write outside this size."""),
+  FunctionType(struct12bytesFloat.memberTypes, struct12bytesFloat, """
+Return value in FPU registers, but does not use all registers on arm hardfp
+and arm64."""),
+  FunctionType(struct16bytesFloat.memberTypes, struct16bytesFloat, """
+Return value in FPU registers on arm hardfp and arm64."""),
+  FunctionType(struct16bytesMixed.memberTypes, struct16bytesMixed, """
+Return value split over FP and integer register in x64."""),
+  FunctionType(struct16bytesMixed2.memberTypes, struct16bytesMixed2, """
+Return value split over FP and integer register in x64.
+The integer register contains half float half int."""),
+  FunctionType(struct17bytesInt.memberTypes, struct17bytesInt, """
+Rerturn value returned in preallocated space passed by pointer on most ABIs.
+Is non word size on purpose, to test that structs are rounded up to word size
+on all ABIs."""),
+  FunctionType(struct19bytesInt.memberTypes, struct19bytesInt, """
+The minimum alignment of this struct is only 1 byte based on its fields.
+Test that the memory backing these structs is the right size and that
+dart:ffi trampolines do not write outside this size."""),
+  FunctionType(struct20bytesInt.memberTypes, struct20bytesInt, """
+Return value too big to go in cpu registers on arm64."""),
+  FunctionType(struct20bytesFloat.memberTypes, struct20bytesFloat, """
+Return value too big to go in FPU registers on x64, arm hardfp and arm64."""),
+  FunctionType(struct32bytesDouble.memberTypes, struct32bytesDouble, """
+Return value in FPU registers on arm64."""),
+  FunctionType(struct40bytesDouble.memberTypes, struct40bytesDouble, """
+Return value too big to go in FPU registers on arm64."""),
+  FunctionType(struct1024bytesInt.memberTypes, struct1024bytesInt, """
+Test 1kb struct."""),
+  FunctionType(
+      [struct1byteInt],
+      struct1byteInt,
+      """
+Test that a struct passed in as argument can be returned.
+Especially for ffi callbacks.
+Struct is passed in int registers in most ABIs."""),
+  FunctionType(
+      [int32, int32, int32, int32, int32, int32, int32, int32, struct1byteInt],
+      struct1byteInt,
+      """
+Test that a struct passed in as argument can be returned.
+Especially for ffi callbacks.
+Struct is passed on stack on all ABIs."""),
+  FunctionType(
+      [struct8bytesFloat],
+      struct8bytesFloat,
+      """
+Test that a struct passed in as argument can be returned.
+Especially for ffi callbacks.
+Struct is passed in float registers in most ABIs."""),
+  FunctionType(
+      [struct20bytesInt],
+      struct20bytesInt,
+      """
+On arm64, both argument and return value are passed in by pointer."""),
+  FunctionType(
+      [
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        struct20bytesInt
+      ],
+      struct20bytesInt,
+      """
+On arm64, both argument and return value are passed in by pointer.
+Ints exhaust registers, so that pointer is passed on stack."""),
+  FunctionType(structAlignmentInt16.memberTypes, structAlignmentInt16, """
+Test alignment and padding of 16 byte int within struct."""),
+  FunctionType(structAlignmentInt32.memberTypes, structAlignmentInt32, """
+Test alignment and padding of 32 byte int within struct."""),
+  FunctionType(structAlignmentInt64.memberTypes, structAlignmentInt64, """
+Test alignment and padding of 64 byte int within struct."""),
+];
+
+final structs = [
+  struct0bytes,
+  struct1byteInt,
+  struct3bytesInt,
+  struct4bytesInt,
+  struct7bytesInt,
+  struct8bytesInt,
+  struct8bytesFloat,
+  struct8BytesMixed,
+  struct9bytesInt,
+  struct9bytesInt2,
+  struct12bytesFloat,
+  struct16bytesFloat,
+  struct16bytesMixed,
+  struct16bytesMixed2,
+  struct17bytesInt,
+  struct19bytesInt,
+  struct20bytesInt,
+  struct20bytesFloat,
+  struct32bytesDouble,
+  struct40bytesDouble,
+  struct1024bytesInt,
+  structAlignmentInt16,
+  structAlignmentInt32,
+  structAlignmentInt64,
+];
+
+/// Using empty structs is undefined behavior in C.
+final struct0bytes = StructType([]);
+
+final struct1byteInt = StructType([int8]);
+final struct3bytesInt = StructType([int16, int8]);
+final struct4bytesInt = StructType([int16, int16]);
+final struct7bytesInt = StructType([int32, int16, int8]);
+final struct8bytesInt = StructType([int16, int16, int32]);
+final struct8bytesFloat = StructType([float, float]);
+final struct8BytesMixed = StructType([float, int16, int16]);
+final struct9bytesInt = StructType([int64, int8]);
+final struct9bytesInt2 = StructType.disambiguate(List.filled(9, uint8), "2");
+final struct12bytesFloat = StructType([float, float, float]);
+
+/// The largest homogenous float that goes into FPU registers on softfp and
+/// arm64.
+final struct16bytesFloat = StructType([float, float, float, float]);
+
+/// This struct will be 8 byte aligned on arm.
+final struct16bytesMixed = StructType([double_, int64]);
+
+/// This struct will be 4 byte aligned on arm.
+final struct16bytesMixed2 =
+    StructType.disambiguate([float, float, float, int32], "2");
+
+final struct17bytesInt = StructType([int64, int64, int8]);
+
+/// This struct has only 1 byte field-alignmnent requirements.
+final struct19bytesInt = StructType(List.filled(19, uint8));
+
+/// The first homogenous integer struct that does not go into registers
+/// anymore on arm64.
+final struct20bytesInt = StructType([int32, int32, int32, int32, int32]);
+
+/// The first homogenous float that does not go into FPU registers anymore on
+/// softfp and arm64.
+final struct20bytesFloat = StructType([float, float, float, float, float]);
+
+/// Largest homogenous doubles in arm64 that goes into FPU registers.
+final struct32bytesDouble = StructType([double_, double_, double_, double_]);
+
+/// The first homogenous doubles that does not go into FPU registers anymore on
+/// arm64.
+final struct40bytesDouble =
+    StructType([double_, double_, double_, double_, double_]);
+
+final struct1024bytesInt = StructType(List.filled(128, uint64));
+
+final structAlignmentInt16 = StructType([int8, int16, int8]);
+final structAlignmentInt32 = StructType([int8, int32, int8]);
+final structAlignmentInt64 = StructType([int8, int64, int8]);
diff --git a/tests/ffi/generator/structs_by_value_tests_generator.dart b/tests/ffi/generator/structs_by_value_tests_generator.dart
new file mode 100644
index 0000000..e233753
--- /dev/null
+++ b/tests/ffi/generator/structs_by_value_tests_generator.dart
@@ -0,0 +1,930 @@
+// Copyright (c) 2020, 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.
+
+import 'dart:io';
+
+import 'c_types.dart';
+import 'structs_by_value_tests_confguration.dart';
+import 'utils.dart';
+
+/// The test type determines how to convert the arguments into return values
+/// such that the caller knows what to check.
+enum TestType {
+  /// Tested by getting all the individual fields out of the structs and
+  /// summing their values.
+  structArguments,
+
+  /// Tested by passing assigning the arguments to the struct fields.
+  structReturn,
+
+  /// Tested by returning the struct passed in.
+  structReturnArgument,
+}
+
+extension on FunctionType {
+  TestType get testType {
+    if (arguments.containsStructs && returnValue is FundamentalType) {
+      return TestType.structArguments;
+    }
+    if (returnValue is StructType && argumentTypes.contains(returnValue)) {
+      return TestType.structReturnArgument;
+    }
+    if (returnValue is StructType) {
+      if (arguments.length == (returnValue as StructType).members.length) {
+        return TestType.structReturn;
+      }
+    }
+    throw Exception("Unknown test type: $this");
+  }
+}
+
+/// We use the class structure as an algebraic data type in order to keep the
+/// relevant parts of the code generation closer together.
+extension on CType {
+  /// The part of the cout expression after `std::cout` and before the `;`.
+  String coutExpression(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        if (this == uint8 || this == int8) {
+          return "<< static_cast<int>($variableName)";
+        }
+        return "<< $variableName";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.coutExpression("$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A statement recursively outputting all members.
+  String coutStatement(String variableName) {
+    final coutExpr = this.coutExpression(variableName);
+    return 'std::cout << "$variableName = " $coutExpr << "\\n";';
+  }
+}
+
+extension on List<Member> {
+  /// The part of the cout expression after `std::cout` and before the `;`.
+  String coutExpression([String namePrefix = ""]) {
+    String result = '<< "("';
+    result += this
+        .map((m) => m.type.coutExpression("$namePrefix${m.name}"))
+        .join('<< ", "');
+    result += '<< ")"';
+    return result.trimCouts();
+  }
+}
+
+extension on CType {
+  /// A list of statements adding all members recurisvely to `result`.
+  ///
+  /// Both valid in Dart and C.
+  String addToResultStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "result += $variableName;\n";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.addToResultStatements("$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of statements adding all members recurisvely to `result`.
+  ///
+  /// Both valid in Dart and C.
+  String addToResultStatements([String namePrefix = ""]) {
+    return map((m) => m.type.addToResultStatements("$namePrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// A list of statements recursively assigning all members with [a].
+  ///
+  /// Both valid in Dart and C.
+  String assignValueStatements(ArgumentValueAssigner a, String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        return "$variableName = ${a.nextValue(this_)};\n";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.assignValueStatements(a, "$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A list of statements recursively coping all members from [source].
+  ///
+  /// Both valid in Dart and C.
+  String copyValueStatements(String source, String destination) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "$destination = $source;\n";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.copyValueStatements("$source.", "$destination.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of statements recursively assigning all members with [a].
+  ///
+  /// Both valid in Dart and C.
+  String assignValueStatements(ArgumentValueAssigner a,
+      [String namePrefix = ""]) {
+    return map((m) => m.type.assignValueStatements(a, "$namePrefix${m.name}"))
+        .join();
+  }
+
+  /// A list of statements recursively coping all members from [source].
+  ///
+  /// Both valid in Dart and C.
+  String copyValueStatements([sourcePrefix = "", destinationPrefix = ""]) {
+    return map((m) => m.type.copyValueStatements(
+        "$sourcePrefix${m.name}", "$destinationPrefix${m.name}")).join();
+  }
+}
+
+/// A helper class that assigns values to fundamental types.
+///
+/// Also keeps track of a sum of all values, to be used for testing the result.
+class ArgumentValueAssigner {
+  int i = 1;
+  int sum = 0;
+  String nextValue(FundamentalType type) {
+    int argumentValue = i;
+    i++;
+    if (type.isSigned && i % 2 == 0) {
+      argumentValue = -argumentValue;
+    }
+    sum += argumentValue;
+    if (type.isFloatingPoint) {
+      return argumentValue.toDouble().toString();
+    } else {
+      return argumentValue.toString();
+    }
+  }
+
+  String sumValue(FundamentalType type) {
+    if (type.isFloatingPoint) {
+      return sum.toDouble().toString();
+    } else {
+      return sum.toString();
+    }
+  }
+}
+
+extension on CType {
+  /// A list of Dart statements recursively allocating all members.
+  String dartAllocateStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "${dartType} ${variableName};\n";
+
+      case StructType:
+        return "${dartType} ${variableName} = allocate<$dartType>().ref;\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A list of Dart statements allocating as zero or nullptr.
+  String dartAllocateZeroStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "${dartType} ${variableName} = 0;\n";
+        }
+        return "${dartType} ${variableName} = 0.0;\n";
+
+      case StructType:
+        return "${dartType} ${variableName} = ${dartType}();\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of Dart statements recursively allocating all members.
+  String dartAllocateStatements([String namePrefix = ""]) {
+    return map((m) => m.type.dartAllocateStatements("$namePrefix${m.name}"))
+        .join();
+  }
+
+  /// A list of Dart statements as zero or nullptr.
+  String dartAllocateZeroStatements([String namePrefix = ""]) {
+    return map((m) => m.type.dartAllocateZeroStatements("$namePrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// A list of Dart statements recursively freeing all members.
+  String dartFreeStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "";
+
+      case StructType:
+        return "free($variableName.addressOf);\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of Dart statements recursively freeing all members.
+  String dartFreeStatements([String namePrefix = ""]) {
+    return map((m) => m.type.dartFreeStatements("$namePrefix${m.name}")).join();
+  }
+}
+
+extension on CType {
+  /// A list of C statements recursively allocating all members.
+  String cAllocateStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+      case StructType:
+        return "${cType} ${variableName};\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of C statements recursively allocating all members.
+  String cAllocateStatements([String namePrefix = ""]) {
+    return map((m) => m.type.cAllocateStatements("$namePrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// A list of Dart statements recursively checking all members.
+  String dartExpectsStatements(String expected, String actual) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "Expect.equals(${expected}, ${actual});";
+        }
+        assert(this_.isFloatingPoint);
+        return "Expect.approxEquals(${expected}, ${actual});";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.dartExpectsStatements("$expected.", "$actual.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of Dart statements recursively checking all members.
+  String dartExpectsStatements(
+      [String expectedPrefix = "", String actualPrefix = ""]) {
+    return map((m) => m.type.dartExpectsStatements(
+        "$expectedPrefix${m.name}", "$actualPrefix${m.name}")).join();
+  }
+}
+
+extension on CType {
+  /// A list of C statements recursively checking all members.
+  String cExpectsStatements(String expected, String actual) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "CHECK_EQ(${expected}, ${actual});";
+        }
+        assert(this_.isFloatingPoint);
+        return "CHECK_APPROX(${expected}, ${actual});";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.cExpectsStatements("$expected.", "$actual.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A list of C statements recursively checking all members for zero.
+  String cExpectsZeroStatements(String actual) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "CHECK_EQ(0, ${actual});";
+        }
+        assert(this_.isFloatingPoint);
+        return "CHECK_APPROX(0.0, ${actual});";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.cExpectsZeroStatements("$actual.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of C statements recursively checking all members.
+  String cExpectsStatements(
+      [String expectedPrefix = "", String actualPrefix = ""]) {
+    return map((m) => m.type.cExpectsStatements(
+        "$expectedPrefix${m.name}", "$actualPrefix${m.name}")).join();
+  }
+
+  /// A list of C statements recursively checking all members for zero.
+  String cExpectsZeroStatements([String actualPrefix = ""]) {
+    return map((m) => m.type.cExpectsZeroStatements("$actualPrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// Expression denoting the first FundamentalType field.
+  ///
+  /// Both valid in Dart and C.
+  String firstArgumentName(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return variableName;
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.firstArgumentName("$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// Expression denoting the first FundamentalType field.
+  ///
+  /// Both valid in Dart and C.
+  String firstArgumentName([String prefix = ""]) {
+    return this[0].type.firstArgumentName("$prefix${this[0].name}");
+  }
+}
+
+extension on StructType {
+  String dartClass(bool nnbd) {
+    String dartFields = "";
+    for (final member in members) {
+      dartFields += "${member.dartStructField(nnbd)}\n\n";
+    }
+    String toStringBody = members.map((m) => "\$\{${m.name}\}").join(", ");
+    return """
+    class $name extends Struct {
+      $dartFields
+
+      String toString() => "($toStringBody)";
+    }
+    """;
+  }
+
+  String get cDefinition {
+    String cFields = "";
+    for (final member in members) {
+      cFields += "  ${member.cStructField}\n";
+    }
+    return """
+    struct $name {
+      $cFields
+    };
+
+    """;
+  }
+}
+
+extension on FunctionType {
+  String get dartCallCode {
+    final a = ArgumentValueAssigner();
+    final assignValues = arguments.assignValueStatements(a);
+    final argumentFrees = arguments.dartFreeStatements();
+
+    final argumentNames = arguments.map((e) => e.name).join(", ");
+
+    String expects;
+    switch (testType) {
+      case TestType.structArguments:
+        // Check against sum value.
+        final expectedResult = a.sumValue(returnValue as FundamentalType);
+        expects = returnValue.dartExpectsStatements(expectedResult, "result");
+        break;
+      case TestType.structReturn:
+        // Check against input arguments.
+        expects = arguments.dartExpectsStatements("", "result.");
+        break;
+      case TestType.structReturnArgument:
+        expects = returnValue.dartExpectsStatements(
+            structReturnArgument.name, "result");
+        break;
+    }
+
+    return """
+    final $dartName =
+      ffiTestFunctions.lookupFunction<$dartCType, $dartType>("$cName");
+
+    ${reason.makeDartDocComment()}
+    void $dartTestName() {
+      ${arguments.dartAllocateStatements()}
+
+      ${assignValues}
+
+      final result = $dartName($argumentNames);
+
+      print("result = \$result");
+
+      $expects
+
+      $argumentFrees
+    }
+    """;
+  }
+
+  String dartCallbackCode(bool nnbd) {
+    final argumentss =
+        arguments.map((a) => "${a.type.dartType} ${a.name}").join(", ");
+
+    final prints = arguments.map((a) => "\$\{${a.name}\}").join(", ");
+
+    String buildReturnValue = "";
+    switch (testType) {
+      case TestType.structArguments:
+        // Sum all input values.
+        buildReturnValue = """
+        ${returnValue.dartType} result = 0;
+
+        ${arguments.addToResultStatements('${dartName}_')}
+        """;
+        break;
+      case TestType.structReturn:
+        // Allocate a struct.
+        buildReturnValue = """
+        ${returnValue.dartType} result = allocate<${returnValue.dartType}>().ref;
+
+        ${arguments.copyValueStatements("${dartName}_", "result.")}
+        """;
+        break;
+      case TestType.structReturnArgument:
+        buildReturnValue = """
+        ${returnValue.cType} result = ${dartName}_${structReturnArgument.name};
+        """;
+        break;
+    }
+
+    final globals = arguments.dartAllocateZeroStatements("${dartName}_");
+
+    final copyToGlobals =
+        arguments.map((a) => '${dartName}_${a.name} = ${a.name};').join("\n");
+
+    // Simulate assigning values the same way as in C, so that we know what the
+    // final return value should be.
+    final a = ArgumentValueAssigner();
+    arguments.assignValueStatements(a);
+    String afterCallbackExpects = "";
+    String afterCallbackFrees = "";
+    switch (testType) {
+      case TestType.structArguments:
+        // Check that the input structs are still available.
+        // Check against sum value.
+        final expectedResult = a.sumValue(returnValue as FundamentalType);
+        afterCallbackExpects =
+            returnValue.dartExpectsStatements(expectedResult, "result");
+        break;
+      case TestType.structReturn:
+        // We're passing allocating structs in [buildReturnValue].
+        afterCallbackFrees =
+            returnValue.dartFreeStatements("${dartName}Result");
+        break;
+      case TestType.structReturnArgument:
+        break;
+    }
+
+    String returnNull = "";
+    if (!nnbd) {
+      returnNull = """
+      if (${arguments.firstArgumentName()} == $returnNullValue) {
+        print("returning null!");
+        return null;
+      }
+      """;
+    }
+
+    return """
+    typedef ${cName}Type = $dartCType;
+
+    // Global variables to be able to test inputs after callback returned.
+    $globals
+
+    // Result variable also global, so we can delete it after the callback.
+    ${returnValue.dartAllocateZeroStatements("${dartName}Result")}
+
+    ${returnValue.dartType} ${dartName}CalculateResult() {
+      $buildReturnValue
+
+      ${dartName}Result = result;
+
+      return result;
+    }
+
+    ${reason.makeDartDocComment()}
+    ${returnValue.dartType} $dartName($argumentss) {
+      print("$dartName($prints)");
+
+      // In legacy mode, possibly return null.
+      $returnNull
+
+      // In both nnbd and legacy mode, possibly throw.
+      if (${arguments.firstArgumentName()} == $throwExceptionValue ||
+          ${arguments.firstArgumentName()} == $returnNullValue) {
+        print("throwing!");
+        throw Exception("$cName throwing on purpuse!");
+      }
+
+      $copyToGlobals
+
+      final result = ${dartName}CalculateResult();
+
+      print(\"result = \$result\");
+
+      return result;
+    }
+
+    void ${dartName}AfterCallback() {
+      $afterCallbackFrees
+
+      final result = ${dartName}CalculateResult();
+
+      print(\"after callback result = \$result\");
+
+      $afterCallbackExpects
+
+      $afterCallbackFrees
+    }
+
+    """;
+  }
+
+  String get dartCallbackTestConstructor {
+    String exceptionalReturn = "";
+    if (returnValue is FundamentalType) {
+      if ((returnValue as FundamentalType).isFloatingPoint) {
+        exceptionalReturn = ", 0.0";
+      } else {
+        exceptionalReturn = ", 0";
+      }
+    }
+    return """
+    CallbackTest.withCheck("$cName",
+      Pointer.fromFunction<${cName}Type>($dartName$exceptionalReturn),
+      ${dartName}AfterCallback),
+    """;
+  }
+
+  String get cCallCode {
+    String body = "";
+    switch (testType) {
+      case TestType.structArguments:
+        body = """
+        ${returnValue.cType} result = 0;
+
+        ${arguments.addToResultStatements()}
+        """;
+        break;
+      case TestType.structReturn:
+        body = """
+        ${returnValue.cType} result;
+
+        ${arguments.copyValueStatements("", "result.")}
+        """;
+        break;
+      case TestType.structReturnArgument:
+        body = """
+        ${returnValue.cType} result = ${structReturnArgument.name};
+        """;
+        break;
+    }
+
+    final argumentss =
+        arguments.map((e) => "${e.type.cType} ${e.name}").join(", ");
+
+    return """
+    // Used for testing structs by value.
+    ${reason.makeCComment()}
+    DART_EXPORT ${returnValue.cType} $cName($argumentss) {
+      std::cout << \"$cName\" ${arguments.coutExpression()} << \"\\n\";
+
+      $body
+
+      ${returnValue.coutStatement("result")}
+
+      return result;
+    }
+
+    """;
+  }
+
+  String get cCallbackCode {
+    final a = ArgumentValueAssigner();
+    final argumentAllocations = arguments.cAllocateStatements();
+    final assignValues = arguments.assignValueStatements(a);
+
+    final argumentss =
+        arguments.map((e) => "${e.type.cType} ${e.name}").join(", ");
+
+    final argumentNames = arguments.map((e) => e.name).join(", ");
+
+    String expects = "";
+    String expectsZero = "";
+    switch (testType) {
+      case TestType.structArguments:
+        // Check against sum value.
+        final returnValue_ = returnValue as FundamentalType;
+        final expectedResult = a.sumValue(returnValue_);
+        expects = returnValue.cExpectsStatements(expectedResult, "result");
+
+        expectsZero = returnValue.cExpectsZeroStatements("result");
+        break;
+      case TestType.structReturn:
+        // Check against input statements.
+        expects = arguments.cExpectsStatements("", "result.");
+
+        expectsZero = arguments.cExpectsZeroStatements("result.");
+        break;
+      case TestType.structReturnArgument:
+        // Check against input struct fields.
+        expects =
+            returnValue.cExpectsStatements(structReturnArgument.name, "result");
+
+        expectsZero = returnValue.cExpectsZeroStatements("result");
+        break;
+    }
+
+    return """
+    // Used for testing structs by value.
+    ${reason.makeCComment()}
+    DART_EXPORT intptr_t
+    Test$cName(
+        // NOLINTNEXTLINE(whitespace/parens)
+        ${returnValue.cType} (*f)($argumentss)) {
+      $argumentAllocations
+
+      $assignValues
+
+      std::cout << \"Calling Test$cName(\" ${arguments.coutExpression()} << \")\\n\";
+
+      ${returnValue.cType} result = f($argumentNames);
+
+      ${returnValue.coutStatement("result")}
+
+      $expects
+
+      // Pass argument that will make the Dart callback throw.
+      ${arguments.firstArgumentName()} = $throwExceptionValue;
+
+      result = f($argumentNames);
+
+      $expectsZero
+
+      // Pass argument that will make the Dart callback return null.
+      ${arguments.firstArgumentName()} = $returnNullValue;
+
+      result = f($argumentNames);
+
+      $expectsZero
+
+      return 0;
+    }
+
+    """;
+  }
+}
+
+/// Some value between 0 and 127 (works in every native type).
+const throwExceptionValue = 42;
+
+/// Some value between 0 and 127 (works in every native type).
+const returnNullValue = 84;
+
+const headerDartCallTest = """
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=5
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'dylib_utils.dart';
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+""";
+
+void writeDartCallTest() {
+  for (bool nnbd in [true, false]) {
+    final StringBuffer buffer = StringBuffer();
+    buffer.write(headerDartCallTest);
+
+    buffer.write("""
+    void main() {
+      for (int i = 0; i < 10; ++i) {
+        ${functions.map((e) => "${e.dartTestName}();").join("\n")}
+      }
+    }
+    """);
+    buffer.writeAll(structs.map((e) => e.dartClass(nnbd)));
+    buffer.writeAll(functions.map((e) => e.dartCallCode));
+
+    final path = callTestPath(nnbd);
+    File(path).writeAsStringSync(buffer.toString());
+    Process.runSync("dartfmt", ["-w", path]);
+  }
+}
+
+String callTestPath(bool nnbd) {
+  final folder = nnbd ? "ffi" : "ffi_2";
+  return Platform.script
+      .resolve("../../$folder/function_structs_by_value_generated_test.dart")
+      .path;
+}
+
+const headerDartCallbackTest = """
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'callback_tests_utils.dart';
+
+// Reuse the struct classes.
+import 'function_structs_by_value_generated_test.dart';
+
+
+void main() {
+  testCases.forEach((t) {
+    print("==== Running " + t.name);
+    t.run();
+  });
+}
+
+
+""";
+
+void writeDartCallbackTest() {
+  for (bool nnbd in [true, false]) {
+    final StringBuffer buffer = StringBuffer();
+    buffer.write(headerDartCallbackTest);
+
+    buffer.write("""
+  final testCases = [
+    ${functions.map((e) => e.dartCallbackTestConstructor).join("\n")}
+  ];
+  """);
+
+    buffer.writeAll(functions.map((e) => e.dartCallbackCode(nnbd)));
+
+    final path = callbackTestPath(nnbd);
+    File(path).writeAsStringSync(buffer.toString());
+    Process.runSync("dartfmt", ["-w", path]);
+  }
+}
+
+String callbackTestPath(bool nnbd) {
+  final folder = nnbd ? "ffi" : "ffi_2";
+  return Platform.script
+      .resolve(
+          "../../$folder/function_callbacks_structs_by_value_generated_test.dart")
+      .path;
+}
+
+const headerC = """
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+#if defined(_WIN32)
+#define DART_EXPORT extern "C" __declspec(dllexport)
+#else
+#define DART_EXPORT                                                            \\
+  extern "C" __attribute__((visibility("default"))) __attribute((used))
+#endif
+
+namespace dart {
+
+#define CHECK(X)                                                               \\
+  if (!(X)) {                                                                  \\
+    fprintf(stderr, "%s\\n", "Check failed: " #X);                              \\
+    return 1;                                                                  \\
+  }
+
+#define CHECK_EQ(X, Y) CHECK((X) == (Y))
+
+// Works for positive, negative and zero.
+#define CHECK_APPROX(EXPECTED, ACTUAL)                                         \\
+  CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) ||    \\
+        ((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
+
+""";
+
+const footerC = """
+
+}  // namespace dart
+""";
+
+void writeC() {
+  final StringBuffer buffer = StringBuffer();
+  buffer.write(headerC);
+
+  buffer.writeAll(structs.map((e) => e.cDefinition));
+  buffer.writeAll(functions.map((e) => e.cCallCode));
+  buffer.writeAll(functions.map((e) => e.cCallbackCode));
+
+  buffer.write(footerC);
+
+  File(ccPath).writeAsStringSync(buffer.toString());
+  Process.runSync("clang-format", ["-i", ccPath]);
+}
+
+final ccPath = Platform.script
+    .resolve("../../../runtime/bin/ffi_test/ffi_test_functions_generated.cc")
+    .path;
+
+void printUsage() {
+  print("""
+Generates structs by value tests.
+
+Generates:
+- $ccPath
+- ${callbackTestPath(true)}
+- ${callTestPath(true)}
+- ${callbackTestPath(false)}
+- ${callTestPath(false)}
+""");
+}
+
+void main(List<String> arguments) {
+  if (arguments.length != 0) {
+    printUsage();
+    return;
+  }
+
+  writeDartCallTest();
+  writeDartCallbackTest();
+  writeC();
+}
diff --git a/tests/ffi/generator/utils.dart b/tests/ffi/generator/utils.dart
new file mode 100644
index 0000000..735e769
--- /dev/null
+++ b/tests/ffi/generator/utils.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2020, 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.
+
+extension TestGeneratorStringExtension on String {
+  String upperCaseFirst() => "${this[0].toUpperCase()}${this.substring(1)}";
+
+  String lowerCaseFirst() => "${this[0].toLowerCase()}${this.substring(1)}";
+
+  String makeCComment() => "// " + split("\n").join("\n// ");
+
+  String makeDartDocComment() => "/// " + split("\n").join("\n/// ");
+
+  String limitTo(int lenght) {
+    if (this.length > lenght) {
+      return substring(0, lenght);
+    }
+    return this;
+  }
+
+  String trimCouts() => replaceAll('" << "', '').replaceAll('"<< "', '');
+}
diff --git a/tests/ffi_2/callback_tests_utils.dart b/tests/ffi_2/callback_tests_utils.dart
index ac5fdcb..e34a52b 100644
--- a/tests/ffi_2/callback_tests_utils.dart
+++ b/tests/ffi_2/callback_tests_utils.dart
@@ -16,19 +16,23 @@
 class CallbackTest {
   final String name;
   final Pointer callback;
-  final bool skip;
+  final void Function() afterCallbackChecks;
 
-  CallbackTest(this.name, this.callback, {bool skipIf: false})
-      : skip = skipIf {}
+  CallbackTest(this.name, this.callback) : afterCallbackChecks = noChecks {}
+  CallbackTest.withCheck(this.name, this.callback, this.afterCallbackChecks) {}
 
   void run() {
-    if (skip) return;
-
     final NativeCallbackTestFn tester = ffiTestFunctions
         .lookupFunction<NativeCallbackTest, NativeCallbackTestFn>("Test$name");
+
     final int testCode = tester(callback);
+
     if (testCode != 0) {
       Expect.fail("Test $name failed.");
     }
+
+    afterCallbackChecks();
   }
 }
+
+void noChecks() {}
diff --git a/tests/ffi_2/ffi_2.status b/tests/ffi_2/ffi_2.status
index 37ab3e9..3baf069 100644
--- a/tests/ffi_2/ffi_2.status
+++ b/tests/ffi_2/ffi_2.status
@@ -2,6 +2,11 @@
 # 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.
 
+# TODO(dartbug.com/36730): Implement structs by value.
+function_callbacks_structs_by_value_generated_test: Skip
+function_callbacks_structs_by_value_test: Skip
+function_structs_by_value_generated_test: Skip
+
 [ $builder_tag == msan ]
 vmspecific_handle_test: Skip # https://dartbug.com/42314
 
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
new file mode 100644
index 0000000..4db290f
--- /dev/null
+++ b/tests/ffi_2/function_callbacks_structs_by_value_generated_test.dart
@@ -0,0 +1,6124 @@
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'callback_tests_utils.dart';
+
+// Reuse the struct classes.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  testCases.forEach((t) {
+    print("==== Running " + t.name);
+    t.run();
+  });
+}
+
+final testCases = [
+  CallbackTest.withCheck(
+      "PassStruct1ByteIntx10",
+      Pointer.fromFunction<PassStruct1ByteIntx10Type>(passStruct1ByteIntx10, 0),
+      passStruct1ByteIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct3BytesIntx10",
+      Pointer.fromFunction<PassStruct3BytesIntx10Type>(
+          passStruct3BytesIntx10, 0),
+      passStruct3BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct4BytesHomogeneousInt16x10",
+      Pointer.fromFunction<PassStruct4BytesHomogeneousInt16x10Type>(
+          passStruct4BytesHomogeneousInt16x10, 0),
+      passStruct4BytesHomogeneousInt16x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct7BytesIntx10",
+      Pointer.fromFunction<PassStruct7BytesIntx10Type>(
+          passStruct7BytesIntx10, 0),
+      passStruct7BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesIntx10",
+      Pointer.fromFunction<PassStruct8BytesIntx10Type>(
+          passStruct8BytesIntx10, 0),
+      passStruct8BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesHomogeneousFloatx10",
+      Pointer.fromFunction<PassStruct8BytesHomogeneousFloatx10Type>(
+          passStruct8BytesHomogeneousFloatx10, 0.0),
+      passStruct8BytesHomogeneousFloatx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct8BytesMixedx10",
+      Pointer.fromFunction<PassStruct8BytesMixedx10Type>(
+          passStruct8BytesMixedx10, 0.0),
+      passStruct8BytesMixedx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct9BytesIntx10",
+      Pointer.fromFunction<PassStruct9BytesIntx10Type>(
+          passStruct9BytesIntx10, 0),
+      passStruct9BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct9BytesHomogeneousUint82x10",
+      Pointer.fromFunction<PassStruct9BytesHomogeneousUint82x10Type>(
+          passStruct9BytesHomogeneousUint82x10, 0),
+      passStruct9BytesHomogeneousUint82x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct12BytesHomogeneousFloatx6",
+      Pointer.fromFunction<PassStruct12BytesHomogeneousFloatx6Type>(
+          passStruct12BytesHomogeneousFloatx6, 0.0),
+      passStruct12BytesHomogeneousFloatx6AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct16BytesHomogeneousFloatx5",
+      Pointer.fromFunction<PassStruct16BytesHomogeneousFloatx5Type>(
+          passStruct16BytesHomogeneousFloatx5, 0.0),
+      passStruct16BytesHomogeneousFloatx5AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct16BytesMixedx10",
+      Pointer.fromFunction<PassStruct16BytesMixedx10Type>(
+          passStruct16BytesMixedx10, 0.0),
+      passStruct16BytesMixedx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct16BytesMixed2x10",
+      Pointer.fromFunction<PassStruct16BytesMixed2x10Type>(
+          passStruct16BytesMixed2x10, 0.0),
+      passStruct16BytesMixed2x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct17BytesIntx10",
+      Pointer.fromFunction<PassStruct17BytesIntx10Type>(
+          passStruct17BytesIntx10, 0),
+      passStruct17BytesIntx10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct19BytesHomogeneousUint8x10",
+      Pointer.fromFunction<PassStruct19BytesHomogeneousUint8x10Type>(
+          passStruct19BytesHomogeneousUint8x10, 0),
+      passStruct19BytesHomogeneousUint8x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct20BytesHomogeneousInt32x10",
+      Pointer.fromFunction<PassStruct20BytesHomogeneousInt32x10Type>(
+          passStruct20BytesHomogeneousInt32x10, 0),
+      passStruct20BytesHomogeneousInt32x10AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct20BytesHomogeneousFloat",
+      Pointer.fromFunction<PassStruct20BytesHomogeneousFloatType>(
+          passStruct20BytesHomogeneousFloat, 0.0),
+      passStruct20BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct32BytesHomogeneousDoublex5",
+      Pointer.fromFunction<PassStruct32BytesHomogeneousDoublex5Type>(
+          passStruct32BytesHomogeneousDoublex5, 0.0),
+      passStruct32BytesHomogeneousDoublex5AfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct40BytesHomogeneousDouble",
+      Pointer.fromFunction<PassStruct40BytesHomogeneousDoubleType>(
+          passStruct40BytesHomogeneousDouble, 0.0),
+      passStruct40BytesHomogeneousDoubleAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct1024BytesHomogeneousUint64",
+      Pointer.fromFunction<PassStruct1024BytesHomogeneousUint64Type>(
+          passStruct1024BytesHomogeneousUint64, 0),
+      passStruct1024BytesHomogeneousUint64AfterCallback),
+  CallbackTest.withCheck(
+      "PassFloatStruct16BytesHomogeneousFloatFloatStruct1",
+      Pointer.fromFunction<
+              PassFloatStruct16BytesHomogeneousFloatFloatStruct1Type>(
+          passFloatStruct16BytesHomogeneousFloatFloatStruct1, 0.0),
+      passFloatStruct16BytesHomogeneousFloatFloatStruct1AfterCallback),
+  CallbackTest.withCheck(
+      "PassFloatStruct32BytesHomogeneousDoubleFloatStruct",
+      Pointer.fromFunction<
+              PassFloatStruct32BytesHomogeneousDoubleFloatStructType>(
+          passFloatStruct32BytesHomogeneousDoubleFloatStruct, 0.0),
+      passFloatStruct32BytesHomogeneousDoubleFloatStructAfterCallback),
+  CallbackTest.withCheck(
+      "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn",
+      Pointer.fromFunction<
+              PassInt8Struct16BytesMixedInt8Struct16BytesMixedInType>(
+          passInt8Struct16BytesMixedInt8Struct16BytesMixedIn, 0.0),
+      passInt8Struct16BytesMixedInt8Struct16BytesMixedInAfterCallback),
+  CallbackTest.withCheck(
+      "PassDoublex6Struct16BytesMixedx4Int32",
+      Pointer.fromFunction<PassDoublex6Struct16BytesMixedx4Int32Type>(
+          passDoublex6Struct16BytesMixedx4Int32, 0.0),
+      passDoublex6Struct16BytesMixedx4Int32AfterCallback),
+  CallbackTest.withCheck(
+      "PassInt32x4Struct16BytesMixedx4Double",
+      Pointer.fromFunction<PassInt32x4Struct16BytesMixedx4DoubleType>(
+          passInt32x4Struct16BytesMixedx4Double, 0.0),
+      passInt32x4Struct16BytesMixedx4DoubleAfterCallback),
+  CallbackTest.withCheck(
+      "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo",
+      Pointer.fromFunction<
+              PassStruct40BytesHomogeneousDoubleStruct4BytesHomoType>(
+          passStruct40BytesHomogeneousDoubleStruct4BytesHomo, 0.0),
+      passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback),
+  CallbackTest.withCheck(
+      "PassStructAlignmentInt16",
+      Pointer.fromFunction<PassStructAlignmentInt16Type>(
+          passStructAlignmentInt16, 0),
+      passStructAlignmentInt16AfterCallback),
+  CallbackTest.withCheck(
+      "PassStructAlignmentInt32",
+      Pointer.fromFunction<PassStructAlignmentInt32Type>(
+          passStructAlignmentInt32, 0),
+      passStructAlignmentInt32AfterCallback),
+  CallbackTest.withCheck(
+      "PassStructAlignmentInt64",
+      Pointer.fromFunction<PassStructAlignmentInt64Type>(
+          passStructAlignmentInt64, 0),
+      passStructAlignmentInt64AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct1ByteInt",
+      Pointer.fromFunction<ReturnStruct1ByteIntType>(returnStruct1ByteInt),
+      returnStruct1ByteIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct3BytesInt",
+      Pointer.fromFunction<ReturnStruct3BytesIntType>(returnStruct3BytesInt),
+      returnStruct3BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct4BytesHomogeneousInt16",
+      Pointer.fromFunction<ReturnStruct4BytesHomogeneousInt16Type>(
+          returnStruct4BytesHomogeneousInt16),
+      returnStruct4BytesHomogeneousInt16AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct7BytesInt",
+      Pointer.fromFunction<ReturnStruct7BytesIntType>(returnStruct7BytesInt),
+      returnStruct7BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesInt",
+      Pointer.fromFunction<ReturnStruct8BytesIntType>(returnStruct8BytesInt),
+      returnStruct8BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct8BytesHomogeneousFloatType>(
+          returnStruct8BytesHomogeneousFloat),
+      returnStruct8BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct8BytesMixed",
+      Pointer.fromFunction<ReturnStruct8BytesMixedType>(
+          returnStruct8BytesMixed),
+      returnStruct8BytesMixedAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct9BytesInt",
+      Pointer.fromFunction<ReturnStruct9BytesIntType>(returnStruct9BytesInt),
+      returnStruct9BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct9BytesHomogeneousUint82",
+      Pointer.fromFunction<ReturnStruct9BytesHomogeneousUint82Type>(
+          returnStruct9BytesHomogeneousUint82),
+      returnStruct9BytesHomogeneousUint82AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct12BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct12BytesHomogeneousFloatType>(
+          returnStruct12BytesHomogeneousFloat),
+      returnStruct12BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct16BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct16BytesHomogeneousFloatType>(
+          returnStruct16BytesHomogeneousFloat),
+      returnStruct16BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct16BytesMixed",
+      Pointer.fromFunction<ReturnStruct16BytesMixedType>(
+          returnStruct16BytesMixed),
+      returnStruct16BytesMixedAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct16BytesMixed2",
+      Pointer.fromFunction<ReturnStruct16BytesMixed2Type>(
+          returnStruct16BytesMixed2),
+      returnStruct16BytesMixed2AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct17BytesInt",
+      Pointer.fromFunction<ReturnStruct17BytesIntType>(returnStruct17BytesInt),
+      returnStruct17BytesIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct19BytesHomogeneousUint8",
+      Pointer.fromFunction<ReturnStruct19BytesHomogeneousUint8Type>(
+          returnStruct19BytesHomogeneousUint8),
+      returnStruct19BytesHomogeneousUint8AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct20BytesHomogeneousInt32",
+      Pointer.fromFunction<ReturnStruct20BytesHomogeneousInt32Type>(
+          returnStruct20BytesHomogeneousInt32),
+      returnStruct20BytesHomogeneousInt32AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct20BytesHomogeneousFloat",
+      Pointer.fromFunction<ReturnStruct20BytesHomogeneousFloatType>(
+          returnStruct20BytesHomogeneousFloat),
+      returnStruct20BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct32BytesHomogeneousDouble",
+      Pointer.fromFunction<ReturnStruct32BytesHomogeneousDoubleType>(
+          returnStruct32BytesHomogeneousDouble),
+      returnStruct32BytesHomogeneousDoubleAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct40BytesHomogeneousDouble",
+      Pointer.fromFunction<ReturnStruct40BytesHomogeneousDoubleType>(
+          returnStruct40BytesHomogeneousDouble),
+      returnStruct40BytesHomogeneousDoubleAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStruct1024BytesHomogeneousUint64",
+      Pointer.fromFunction<ReturnStruct1024BytesHomogeneousUint64Type>(
+          returnStruct1024BytesHomogeneousUint64),
+      returnStruct1024BytesHomogeneousUint64AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentStruct1ByteInt",
+      Pointer.fromFunction<ReturnStructArgumentStruct1ByteIntType>(
+          returnStructArgumentStruct1ByteInt),
+      returnStructArgumentStruct1ByteIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentInt32x8Struct1ByteInt",
+      Pointer.fromFunction<ReturnStructArgumentInt32x8Struct1ByteIntType>(
+          returnStructArgumentInt32x8Struct1ByteInt),
+      returnStructArgumentInt32x8Struct1ByteIntAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentStruct8BytesHomogeneousFloat",
+      Pointer.fromFunction<
+              ReturnStructArgumentStruct8BytesHomogeneousFloatType>(
+          returnStructArgumentStruct8BytesHomogeneousFloat),
+      returnStructArgumentStruct8BytesHomogeneousFloatAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentStruct20BytesHomogeneousInt32",
+      Pointer.fromFunction<
+              ReturnStructArgumentStruct20BytesHomogeneousInt32Type>(
+          returnStructArgumentStruct20BytesHomogeneousInt32),
+      returnStructArgumentStruct20BytesHomogeneousInt32AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructArgumentInt32x8Struct20BytesHomogeneou",
+      Pointer.fromFunction<
+              ReturnStructArgumentInt32x8Struct20BytesHomogeneouType>(
+          returnStructArgumentInt32x8Struct20BytesHomogeneou),
+      returnStructArgumentInt32x8Struct20BytesHomogeneouAfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructAlignmentInt16",
+      Pointer.fromFunction<ReturnStructAlignmentInt16Type>(
+          returnStructAlignmentInt16),
+      returnStructAlignmentInt16AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructAlignmentInt32",
+      Pointer.fromFunction<ReturnStructAlignmentInt32Type>(
+          returnStructAlignmentInt32),
+      returnStructAlignmentInt32AfterCallback),
+  CallbackTest.withCheck(
+      "ReturnStructAlignmentInt64",
+      Pointer.fromFunction<ReturnStructAlignmentInt64Type>(
+          returnStructAlignmentInt64),
+      returnStructAlignmentInt64AfterCallback),
+];
+typedef PassStruct1ByteIntx10Type = Int64 Function(
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt,
+    Struct1ByteInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct1ByteInt passStruct1ByteIntx10_a0 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a1 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a2 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a3 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a4 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a5 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a6 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a7 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a8 = Struct1ByteInt();
+Struct1ByteInt passStruct1ByteIntx10_a9 = Struct1ByteInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct1ByteIntx10Result = 0;
+
+int passStruct1ByteIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct1ByteIntx10_a0.a0;
+  result += passStruct1ByteIntx10_a1.a0;
+  result += passStruct1ByteIntx10_a2.a0;
+  result += passStruct1ByteIntx10_a3.a0;
+  result += passStruct1ByteIntx10_a4.a0;
+  result += passStruct1ByteIntx10_a5.a0;
+  result += passStruct1ByteIntx10_a6.a0;
+  result += passStruct1ByteIntx10_a7.a0;
+  result += passStruct1ByteIntx10_a8.a0;
+  result += passStruct1ByteIntx10_a9.a0;
+
+  passStruct1ByteIntx10Result = result;
+
+  return result;
+}
+
+/// Smallest struct with data.
+/// 10 struct arguments will exhaust available registers.
+int passStruct1ByteIntx10(
+    Struct1ByteInt a0,
+    Struct1ByteInt a1,
+    Struct1ByteInt a2,
+    Struct1ByteInt a3,
+    Struct1ByteInt a4,
+    Struct1ByteInt a5,
+    Struct1ByteInt a6,
+    Struct1ByteInt a7,
+    Struct1ByteInt a8,
+    Struct1ByteInt a9) {
+  print(
+      "passStruct1ByteIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct1ByteIntx10 throwing on purpuse!");
+  }
+
+  passStruct1ByteIntx10_a0 = a0;
+  passStruct1ByteIntx10_a1 = a1;
+  passStruct1ByteIntx10_a2 = a2;
+  passStruct1ByteIntx10_a3 = a3;
+  passStruct1ByteIntx10_a4 = a4;
+  passStruct1ByteIntx10_a5 = a5;
+  passStruct1ByteIntx10_a6 = a6;
+  passStruct1ByteIntx10_a7 = a7;
+  passStruct1ByteIntx10_a8 = a8;
+  passStruct1ByteIntx10_a9 = a9;
+
+  final result = passStruct1ByteIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct1ByteIntx10AfterCallback() {
+  final result = passStruct1ByteIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(5, result);
+}
+
+typedef PassStruct3BytesIntx10Type = Int64 Function(
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt,
+    Struct3BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct3BytesInt passStruct3BytesIntx10_a0 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a1 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a2 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a3 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a4 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a5 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a6 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a7 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a8 = Struct3BytesInt();
+Struct3BytesInt passStruct3BytesIntx10_a9 = Struct3BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct3BytesIntx10Result = 0;
+
+int passStruct3BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct3BytesIntx10_a0.a0;
+  result += passStruct3BytesIntx10_a0.a1;
+  result += passStruct3BytesIntx10_a1.a0;
+  result += passStruct3BytesIntx10_a1.a1;
+  result += passStruct3BytesIntx10_a2.a0;
+  result += passStruct3BytesIntx10_a2.a1;
+  result += passStruct3BytesIntx10_a3.a0;
+  result += passStruct3BytesIntx10_a3.a1;
+  result += passStruct3BytesIntx10_a4.a0;
+  result += passStruct3BytesIntx10_a4.a1;
+  result += passStruct3BytesIntx10_a5.a0;
+  result += passStruct3BytesIntx10_a5.a1;
+  result += passStruct3BytesIntx10_a6.a0;
+  result += passStruct3BytesIntx10_a6.a1;
+  result += passStruct3BytesIntx10_a7.a0;
+  result += passStruct3BytesIntx10_a7.a1;
+  result += passStruct3BytesIntx10_a8.a0;
+  result += passStruct3BytesIntx10_a8.a1;
+  result += passStruct3BytesIntx10_a9.a0;
+  result += passStruct3BytesIntx10_a9.a1;
+
+  passStruct3BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Not a multiple of word size, not a power of two.
+/// 10 struct arguments will exhaust available registers.
+int passStruct3BytesIntx10(
+    Struct3BytesInt a0,
+    Struct3BytesInt a1,
+    Struct3BytesInt a2,
+    Struct3BytesInt a3,
+    Struct3BytesInt a4,
+    Struct3BytesInt a5,
+    Struct3BytesInt a6,
+    Struct3BytesInt a7,
+    Struct3BytesInt a8,
+    Struct3BytesInt a9) {
+  print(
+      "passStruct3BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct3BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct3BytesIntx10_a0 = a0;
+  passStruct3BytesIntx10_a1 = a1;
+  passStruct3BytesIntx10_a2 = a2;
+  passStruct3BytesIntx10_a3 = a3;
+  passStruct3BytesIntx10_a4 = a4;
+  passStruct3BytesIntx10_a5 = a5;
+  passStruct3BytesIntx10_a6 = a6;
+  passStruct3BytesIntx10_a7 = a7;
+  passStruct3BytesIntx10_a8 = a8;
+  passStruct3BytesIntx10_a9 = a9;
+
+  final result = passStruct3BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct3BytesIntx10AfterCallback() {
+  final result = passStruct3BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct4BytesHomogeneousInt16x10Type = Int64 Function(
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16,
+    Struct4BytesHomogeneousInt16);
+
+// Global variables to be able to test inputs after callback returned.
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a0 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a1 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a2 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a3 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a4 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a5 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a6 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a7 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a8 =
+    Struct4BytesHomogeneousInt16();
+Struct4BytesHomogeneousInt16 passStruct4BytesHomogeneousInt16x10_a9 =
+    Struct4BytesHomogeneousInt16();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct4BytesHomogeneousInt16x10Result = 0;
+
+int passStruct4BytesHomogeneousInt16x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct4BytesHomogeneousInt16x10_a0.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a0.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a1.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a1.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a2.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a2.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a3.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a3.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a4.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a4.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a5.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a5.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a6.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a6.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a7.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a7.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a8.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a8.a1;
+  result += passStruct4BytesHomogeneousInt16x10_a9.a0;
+  result += passStruct4BytesHomogeneousInt16x10_a9.a1;
+
+  passStruct4BytesHomogeneousInt16x10Result = result;
+
+  return result;
+}
+
+/// Exactly word size on 32-bit architectures.
+/// 10 struct arguments will exhaust available registers.
+int passStruct4BytesHomogeneousInt16x10(
+    Struct4BytesHomogeneousInt16 a0,
+    Struct4BytesHomogeneousInt16 a1,
+    Struct4BytesHomogeneousInt16 a2,
+    Struct4BytesHomogeneousInt16 a3,
+    Struct4BytesHomogeneousInt16 a4,
+    Struct4BytesHomogeneousInt16 a5,
+    Struct4BytesHomogeneousInt16 a6,
+    Struct4BytesHomogeneousInt16 a7,
+    Struct4BytesHomogeneousInt16 a8,
+    Struct4BytesHomogeneousInt16 a9) {
+  print(
+      "passStruct4BytesHomogeneousInt16x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct4BytesHomogeneousInt16x10 throwing on purpuse!");
+  }
+
+  passStruct4BytesHomogeneousInt16x10_a0 = a0;
+  passStruct4BytesHomogeneousInt16x10_a1 = a1;
+  passStruct4BytesHomogeneousInt16x10_a2 = a2;
+  passStruct4BytesHomogeneousInt16x10_a3 = a3;
+  passStruct4BytesHomogeneousInt16x10_a4 = a4;
+  passStruct4BytesHomogeneousInt16x10_a5 = a5;
+  passStruct4BytesHomogeneousInt16x10_a6 = a6;
+  passStruct4BytesHomogeneousInt16x10_a7 = a7;
+  passStruct4BytesHomogeneousInt16x10_a8 = a8;
+  passStruct4BytesHomogeneousInt16x10_a9 = a9;
+
+  final result = passStruct4BytesHomogeneousInt16x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct4BytesHomogeneousInt16x10AfterCallback() {
+  final result = passStruct4BytesHomogeneousInt16x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct7BytesIntx10Type = Int64 Function(
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt,
+    Struct7BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct7BytesInt passStruct7BytesIntx10_a0 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a1 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a2 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a3 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a4 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a5 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a6 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a7 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a8 = Struct7BytesInt();
+Struct7BytesInt passStruct7BytesIntx10_a9 = Struct7BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct7BytesIntx10Result = 0;
+
+int passStruct7BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct7BytesIntx10_a0.a0;
+  result += passStruct7BytesIntx10_a0.a1;
+  result += passStruct7BytesIntx10_a0.a2;
+  result += passStruct7BytesIntx10_a1.a0;
+  result += passStruct7BytesIntx10_a1.a1;
+  result += passStruct7BytesIntx10_a1.a2;
+  result += passStruct7BytesIntx10_a2.a0;
+  result += passStruct7BytesIntx10_a2.a1;
+  result += passStruct7BytesIntx10_a2.a2;
+  result += passStruct7BytesIntx10_a3.a0;
+  result += passStruct7BytesIntx10_a3.a1;
+  result += passStruct7BytesIntx10_a3.a2;
+  result += passStruct7BytesIntx10_a4.a0;
+  result += passStruct7BytesIntx10_a4.a1;
+  result += passStruct7BytesIntx10_a4.a2;
+  result += passStruct7BytesIntx10_a5.a0;
+  result += passStruct7BytesIntx10_a5.a1;
+  result += passStruct7BytesIntx10_a5.a2;
+  result += passStruct7BytesIntx10_a6.a0;
+  result += passStruct7BytesIntx10_a6.a1;
+  result += passStruct7BytesIntx10_a6.a2;
+  result += passStruct7BytesIntx10_a7.a0;
+  result += passStruct7BytesIntx10_a7.a1;
+  result += passStruct7BytesIntx10_a7.a2;
+  result += passStruct7BytesIntx10_a8.a0;
+  result += passStruct7BytesIntx10_a8.a1;
+  result += passStruct7BytesIntx10_a8.a2;
+  result += passStruct7BytesIntx10_a9.a0;
+  result += passStruct7BytesIntx10_a9.a1;
+  result += passStruct7BytesIntx10_a9.a2;
+
+  passStruct7BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Sub word size on 64 bit architectures.
+/// 10 struct arguments will exhaust available registers.
+int passStruct7BytesIntx10(
+    Struct7BytesInt a0,
+    Struct7BytesInt a1,
+    Struct7BytesInt a2,
+    Struct7BytesInt a3,
+    Struct7BytesInt a4,
+    Struct7BytesInt a5,
+    Struct7BytesInt a6,
+    Struct7BytesInt a7,
+    Struct7BytesInt a8,
+    Struct7BytesInt a9) {
+  print(
+      "passStruct7BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct7BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct7BytesIntx10_a0 = a0;
+  passStruct7BytesIntx10_a1 = a1;
+  passStruct7BytesIntx10_a2 = a2;
+  passStruct7BytesIntx10_a3 = a3;
+  passStruct7BytesIntx10_a4 = a4;
+  passStruct7BytesIntx10_a5 = a5;
+  passStruct7BytesIntx10_a6 = a6;
+  passStruct7BytesIntx10_a7 = a7;
+  passStruct7BytesIntx10_a8 = a8;
+  passStruct7BytesIntx10_a9 = a9;
+
+  final result = passStruct7BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct7BytesIntx10AfterCallback() {
+  final result = passStruct7BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(15, result);
+}
+
+typedef PassStruct8BytesIntx10Type = Int64 Function(
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt,
+    Struct8BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesInt passStruct8BytesIntx10_a0 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a1 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a2 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a3 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a4 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a5 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a6 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a7 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a8 = Struct8BytesInt();
+Struct8BytesInt passStruct8BytesIntx10_a9 = Struct8BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct8BytesIntx10Result = 0;
+
+int passStruct8BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct8BytesIntx10_a0.a0;
+  result += passStruct8BytesIntx10_a0.a1;
+  result += passStruct8BytesIntx10_a0.a2;
+  result += passStruct8BytesIntx10_a1.a0;
+  result += passStruct8BytesIntx10_a1.a1;
+  result += passStruct8BytesIntx10_a1.a2;
+  result += passStruct8BytesIntx10_a2.a0;
+  result += passStruct8BytesIntx10_a2.a1;
+  result += passStruct8BytesIntx10_a2.a2;
+  result += passStruct8BytesIntx10_a3.a0;
+  result += passStruct8BytesIntx10_a3.a1;
+  result += passStruct8BytesIntx10_a3.a2;
+  result += passStruct8BytesIntx10_a4.a0;
+  result += passStruct8BytesIntx10_a4.a1;
+  result += passStruct8BytesIntx10_a4.a2;
+  result += passStruct8BytesIntx10_a5.a0;
+  result += passStruct8BytesIntx10_a5.a1;
+  result += passStruct8BytesIntx10_a5.a2;
+  result += passStruct8BytesIntx10_a6.a0;
+  result += passStruct8BytesIntx10_a6.a1;
+  result += passStruct8BytesIntx10_a6.a2;
+  result += passStruct8BytesIntx10_a7.a0;
+  result += passStruct8BytesIntx10_a7.a1;
+  result += passStruct8BytesIntx10_a7.a2;
+  result += passStruct8BytesIntx10_a8.a0;
+  result += passStruct8BytesIntx10_a8.a1;
+  result += passStruct8BytesIntx10_a8.a2;
+  result += passStruct8BytesIntx10_a9.a0;
+  result += passStruct8BytesIntx10_a9.a1;
+  result += passStruct8BytesIntx10_a9.a2;
+
+  passStruct8BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Exactly word size struct on 64bit architectures.
+/// 10 struct arguments will exhaust available registers.
+int passStruct8BytesIntx10(
+    Struct8BytesInt a0,
+    Struct8BytesInt a1,
+    Struct8BytesInt a2,
+    Struct8BytesInt a3,
+    Struct8BytesInt a4,
+    Struct8BytesInt a5,
+    Struct8BytesInt a6,
+    Struct8BytesInt a7,
+    Struct8BytesInt a8,
+    Struct8BytesInt a9) {
+  print(
+      "passStruct8BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct8BytesIntx10_a0 = a0;
+  passStruct8BytesIntx10_a1 = a1;
+  passStruct8BytesIntx10_a2 = a2;
+  passStruct8BytesIntx10_a3 = a3;
+  passStruct8BytesIntx10_a4 = a4;
+  passStruct8BytesIntx10_a5 = a5;
+  passStruct8BytesIntx10_a6 = a6;
+  passStruct8BytesIntx10_a7 = a7;
+  passStruct8BytesIntx10_a8 = a8;
+  passStruct8BytesIntx10_a9 = a9;
+
+  final result = passStruct8BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesIntx10AfterCallback() {
+  final result = passStruct8BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(15, result);
+}
+
+typedef PassStruct8BytesHomogeneousFloatx10Type = Float Function(
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat,
+    Struct8BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a0 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a1 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a2 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a3 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a4 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a5 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a6 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a7 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a8 =
+    Struct8BytesHomogeneousFloat();
+Struct8BytesHomogeneousFloat passStruct8BytesHomogeneousFloatx10_a9 =
+    Struct8BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct8BytesHomogeneousFloatx10Result = 0.0;
+
+double passStruct8BytesHomogeneousFloatx10CalculateResult() {
+  double result = 0;
+
+  result += passStruct8BytesHomogeneousFloatx10_a0.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a0.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a1.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a1.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a2.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a2.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a3.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a3.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a4.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a4.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a5.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a5.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a6.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a6.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a7.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a7.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a8.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a8.a1;
+  result += passStruct8BytesHomogeneousFloatx10_a9.a0;
+  result += passStruct8BytesHomogeneousFloatx10_a9.a1;
+
+  passStruct8BytesHomogeneousFloatx10Result = result;
+
+  return result;
+}
+
+/// Arguments passed in FP registers as long as they fit.
+/// 10 struct arguments will exhaust available registers.
+double passStruct8BytesHomogeneousFloatx10(
+    Struct8BytesHomogeneousFloat a0,
+    Struct8BytesHomogeneousFloat a1,
+    Struct8BytesHomogeneousFloat a2,
+    Struct8BytesHomogeneousFloat a3,
+    Struct8BytesHomogeneousFloat a4,
+    Struct8BytesHomogeneousFloat a5,
+    Struct8BytesHomogeneousFloat a6,
+    Struct8BytesHomogeneousFloat a7,
+    Struct8BytesHomogeneousFloat a8,
+    Struct8BytesHomogeneousFloat a9) {
+  print(
+      "passStruct8BytesHomogeneousFloatx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesHomogeneousFloatx10 throwing on purpuse!");
+  }
+
+  passStruct8BytesHomogeneousFloatx10_a0 = a0;
+  passStruct8BytesHomogeneousFloatx10_a1 = a1;
+  passStruct8BytesHomogeneousFloatx10_a2 = a2;
+  passStruct8BytesHomogeneousFloatx10_a3 = a3;
+  passStruct8BytesHomogeneousFloatx10_a4 = a4;
+  passStruct8BytesHomogeneousFloatx10_a5 = a5;
+  passStruct8BytesHomogeneousFloatx10_a6 = a6;
+  passStruct8BytesHomogeneousFloatx10_a7 = a7;
+  passStruct8BytesHomogeneousFloatx10_a8 = a8;
+  passStruct8BytesHomogeneousFloatx10_a9 = a9;
+
+  final result = passStruct8BytesHomogeneousFloatx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesHomogeneousFloatx10AfterCallback() {
+  final result = passStruct8BytesHomogeneousFloatx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct8BytesMixedx10Type = Float Function(
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed,
+    Struct8BytesMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesMixed passStruct8BytesMixedx10_a0 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a1 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a2 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a3 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a4 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a5 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a6 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a7 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a8 = Struct8BytesMixed();
+Struct8BytesMixed passStruct8BytesMixedx10_a9 = Struct8BytesMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct8BytesMixedx10Result = 0.0;
+
+double passStruct8BytesMixedx10CalculateResult() {
+  double result = 0;
+
+  result += passStruct8BytesMixedx10_a0.a0;
+  result += passStruct8BytesMixedx10_a0.a1;
+  result += passStruct8BytesMixedx10_a0.a2;
+  result += passStruct8BytesMixedx10_a1.a0;
+  result += passStruct8BytesMixedx10_a1.a1;
+  result += passStruct8BytesMixedx10_a1.a2;
+  result += passStruct8BytesMixedx10_a2.a0;
+  result += passStruct8BytesMixedx10_a2.a1;
+  result += passStruct8BytesMixedx10_a2.a2;
+  result += passStruct8BytesMixedx10_a3.a0;
+  result += passStruct8BytesMixedx10_a3.a1;
+  result += passStruct8BytesMixedx10_a3.a2;
+  result += passStruct8BytesMixedx10_a4.a0;
+  result += passStruct8BytesMixedx10_a4.a1;
+  result += passStruct8BytesMixedx10_a4.a2;
+  result += passStruct8BytesMixedx10_a5.a0;
+  result += passStruct8BytesMixedx10_a5.a1;
+  result += passStruct8BytesMixedx10_a5.a2;
+  result += passStruct8BytesMixedx10_a6.a0;
+  result += passStruct8BytesMixedx10_a6.a1;
+  result += passStruct8BytesMixedx10_a6.a2;
+  result += passStruct8BytesMixedx10_a7.a0;
+  result += passStruct8BytesMixedx10_a7.a1;
+  result += passStruct8BytesMixedx10_a7.a2;
+  result += passStruct8BytesMixedx10_a8.a0;
+  result += passStruct8BytesMixedx10_a8.a1;
+  result += passStruct8BytesMixedx10_a8.a2;
+  result += passStruct8BytesMixedx10_a9.a0;
+  result += passStruct8BytesMixedx10_a9.a1;
+  result += passStruct8BytesMixedx10_a9.a2;
+
+  passStruct8BytesMixedx10Result = result;
+
+  return result;
+}
+
+/// On x64, arguments go in int registers because it is not only float.
+/// 10 struct arguments will exhaust available registers.
+double passStruct8BytesMixedx10(
+    Struct8BytesMixed a0,
+    Struct8BytesMixed a1,
+    Struct8BytesMixed a2,
+    Struct8BytesMixed a3,
+    Struct8BytesMixed a4,
+    Struct8BytesMixed a5,
+    Struct8BytesMixed a6,
+    Struct8BytesMixed a7,
+    Struct8BytesMixed a8,
+    Struct8BytesMixed a9) {
+  print(
+      "passStruct8BytesMixedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct8BytesMixedx10 throwing on purpuse!");
+  }
+
+  passStruct8BytesMixedx10_a0 = a0;
+  passStruct8BytesMixedx10_a1 = a1;
+  passStruct8BytesMixedx10_a2 = a2;
+  passStruct8BytesMixedx10_a3 = a3;
+  passStruct8BytesMixedx10_a4 = a4;
+  passStruct8BytesMixedx10_a5 = a5;
+  passStruct8BytesMixedx10_a6 = a6;
+  passStruct8BytesMixedx10_a7 = a7;
+  passStruct8BytesMixedx10_a8 = a8;
+  passStruct8BytesMixedx10_a9 = a9;
+
+  final result = passStruct8BytesMixedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct8BytesMixedx10AfterCallback() {
+  final result = passStruct8BytesMixedx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(15.0, result);
+}
+
+typedef PassStruct9BytesIntx10Type = Int64 Function(
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt,
+    Struct9BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesInt passStruct9BytesIntx10_a0 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a1 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a2 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a3 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a4 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a5 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a6 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a7 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a8 = Struct9BytesInt();
+Struct9BytesInt passStruct9BytesIntx10_a9 = Struct9BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct9BytesIntx10Result = 0;
+
+int passStruct9BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct9BytesIntx10_a0.a0;
+  result += passStruct9BytesIntx10_a0.a1;
+  result += passStruct9BytesIntx10_a1.a0;
+  result += passStruct9BytesIntx10_a1.a1;
+  result += passStruct9BytesIntx10_a2.a0;
+  result += passStruct9BytesIntx10_a2.a1;
+  result += passStruct9BytesIntx10_a3.a0;
+  result += passStruct9BytesIntx10_a3.a1;
+  result += passStruct9BytesIntx10_a4.a0;
+  result += passStruct9BytesIntx10_a4.a1;
+  result += passStruct9BytesIntx10_a5.a0;
+  result += passStruct9BytesIntx10_a5.a1;
+  result += passStruct9BytesIntx10_a6.a0;
+  result += passStruct9BytesIntx10_a6.a1;
+  result += passStruct9BytesIntx10_a7.a0;
+  result += passStruct9BytesIntx10_a7.a1;
+  result += passStruct9BytesIntx10_a8.a0;
+  result += passStruct9BytesIntx10_a8.a1;
+  result += passStruct9BytesIntx10_a9.a0;
+  result += passStruct9BytesIntx10_a9.a1;
+
+  passStruct9BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+int passStruct9BytesIntx10(
+    Struct9BytesInt a0,
+    Struct9BytesInt a1,
+    Struct9BytesInt a2,
+    Struct9BytesInt a3,
+    Struct9BytesInt a4,
+    Struct9BytesInt a5,
+    Struct9BytesInt a6,
+    Struct9BytesInt a7,
+    Struct9BytesInt a8,
+    Struct9BytesInt a9) {
+  print(
+      "passStruct9BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct9BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct9BytesIntx10_a0 = a0;
+  passStruct9BytesIntx10_a1 = a1;
+  passStruct9BytesIntx10_a2 = a2;
+  passStruct9BytesIntx10_a3 = a3;
+  passStruct9BytesIntx10_a4 = a4;
+  passStruct9BytesIntx10_a5 = a5;
+  passStruct9BytesIntx10_a6 = a6;
+  passStruct9BytesIntx10_a7 = a7;
+  passStruct9BytesIntx10_a8 = a8;
+  passStruct9BytesIntx10_a9 = a9;
+
+  final result = passStruct9BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesIntx10AfterCallback() {
+  final result = passStruct9BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(10, result);
+}
+
+typedef PassStruct9BytesHomogeneousUint82x10Type = Int64 Function(
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82,
+    Struct9BytesHomogeneousUint82);
+
+// Global variables to be able to test inputs after callback returned.
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a0 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a1 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a2 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a3 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a4 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a5 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a6 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a7 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a8 =
+    Struct9BytesHomogeneousUint82();
+Struct9BytesHomogeneousUint82 passStruct9BytesHomogeneousUint82x10_a9 =
+    Struct9BytesHomogeneousUint82();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct9BytesHomogeneousUint82x10Result = 0;
+
+int passStruct9BytesHomogeneousUint82x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct9BytesHomogeneousUint82x10_a0.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a0.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a1.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a2.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a3.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a4.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a5.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a6.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a7.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a8.a8;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a0;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a1;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a2;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a3;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a4;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a5;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a6;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a7;
+  result += passStruct9BytesHomogeneousUint82x10_a9.a8;
+
+  passStruct9BytesHomogeneousUint82x10Result = result;
+
+  return result;
+}
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Struct only has 1-byte aligned fields to test struct alignment itself.
+///
+int passStruct9BytesHomogeneousUint82x10(
+    Struct9BytesHomogeneousUint82 a0,
+    Struct9BytesHomogeneousUint82 a1,
+    Struct9BytesHomogeneousUint82 a2,
+    Struct9BytesHomogeneousUint82 a3,
+    Struct9BytesHomogeneousUint82 a4,
+    Struct9BytesHomogeneousUint82 a5,
+    Struct9BytesHomogeneousUint82 a6,
+    Struct9BytesHomogeneousUint82 a7,
+    Struct9BytesHomogeneousUint82 a8,
+    Struct9BytesHomogeneousUint82 a9) {
+  print(
+      "passStruct9BytesHomogeneousUint82x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct9BytesHomogeneousUint82x10 throwing on purpuse!");
+  }
+
+  passStruct9BytesHomogeneousUint82x10_a0 = a0;
+  passStruct9BytesHomogeneousUint82x10_a1 = a1;
+  passStruct9BytesHomogeneousUint82x10_a2 = a2;
+  passStruct9BytesHomogeneousUint82x10_a3 = a3;
+  passStruct9BytesHomogeneousUint82x10_a4 = a4;
+  passStruct9BytesHomogeneousUint82x10_a5 = a5;
+  passStruct9BytesHomogeneousUint82x10_a6 = a6;
+  passStruct9BytesHomogeneousUint82x10_a7 = a7;
+  passStruct9BytesHomogeneousUint82x10_a8 = a8;
+  passStruct9BytesHomogeneousUint82x10_a9 = a9;
+
+  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct9BytesHomogeneousUint82x10AfterCallback() {
+  final result = passStruct9BytesHomogeneousUint82x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(4095, result);
+}
+
+typedef PassStruct12BytesHomogeneousFloatx6Type = Float Function(
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat,
+    Struct12BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a0 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a1 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a2 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a3 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a4 =
+    Struct12BytesHomogeneousFloat();
+Struct12BytesHomogeneousFloat passStruct12BytesHomogeneousFloatx6_a5 =
+    Struct12BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct12BytesHomogeneousFloatx6Result = 0.0;
+
+double passStruct12BytesHomogeneousFloatx6CalculateResult() {
+  double result = 0;
+
+  result += passStruct12BytesHomogeneousFloatx6_a0.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a0.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a0.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a1.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a1.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a1.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a2.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a2.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a2.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a3.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a3.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a3.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a4.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a4.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a4.a2;
+  result += passStruct12BytesHomogeneousFloatx6_a5.a0;
+  result += passStruct12BytesHomogeneousFloatx6_a5.a1;
+  result += passStruct12BytesHomogeneousFloatx6_a5.a2;
+
+  passStruct12BytesHomogeneousFloatx6Result = result;
+
+  return result;
+}
+
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// Struct arguments will exhaust available registers, and leave some empty.
+/// The last argument is to test whether arguments are backfilled.
+double passStruct12BytesHomogeneousFloatx6(
+    Struct12BytesHomogeneousFloat a0,
+    Struct12BytesHomogeneousFloat a1,
+    Struct12BytesHomogeneousFloat a2,
+    Struct12BytesHomogeneousFloat a3,
+    Struct12BytesHomogeneousFloat a4,
+    Struct12BytesHomogeneousFloat a5) {
+  print(
+      "passStruct12BytesHomogeneousFloatx6(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct12BytesHomogeneousFloatx6 throwing on purpuse!");
+  }
+
+  passStruct12BytesHomogeneousFloatx6_a0 = a0;
+  passStruct12BytesHomogeneousFloatx6_a1 = a1;
+  passStruct12BytesHomogeneousFloatx6_a2 = a2;
+  passStruct12BytesHomogeneousFloatx6_a3 = a3;
+  passStruct12BytesHomogeneousFloatx6_a4 = a4;
+  passStruct12BytesHomogeneousFloatx6_a5 = a5;
+
+  final result = passStruct12BytesHomogeneousFloatx6CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct12BytesHomogeneousFloatx6AfterCallback() {
+  final result = passStruct12BytesHomogeneousFloatx6CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(9.0, result);
+}
+
+typedef PassStruct16BytesHomogeneousFloatx5Type = Float Function(
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat,
+    Struct16BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a0 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a1 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a2 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a3 =
+    Struct16BytesHomogeneousFloat();
+Struct16BytesHomogeneousFloat passStruct16BytesHomogeneousFloatx5_a4 =
+    Struct16BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct16BytesHomogeneousFloatx5Result = 0.0;
+
+double passStruct16BytesHomogeneousFloatx5CalculateResult() {
+  double result = 0;
+
+  result += passStruct16BytesHomogeneousFloatx5_a0.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a0.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a0.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a0.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a1.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a2.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a3.a3;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a0;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a1;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a2;
+  result += passStruct16BytesHomogeneousFloatx5_a4.a3;
+
+  passStruct16BytesHomogeneousFloatx5Result = result;
+
+  return result;
+}
+
+/// On Linux x64 argument is transferred on stack because it is over 16 bytes.
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// 5 struct arguments will exhaust available registers.
+double passStruct16BytesHomogeneousFloatx5(
+    Struct16BytesHomogeneousFloat a0,
+    Struct16BytesHomogeneousFloat a1,
+    Struct16BytesHomogeneousFloat a2,
+    Struct16BytesHomogeneousFloat a3,
+    Struct16BytesHomogeneousFloat a4) {
+  print(
+      "passStruct16BytesHomogeneousFloatx5(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct16BytesHomogeneousFloatx5 throwing on purpuse!");
+  }
+
+  passStruct16BytesHomogeneousFloatx5_a0 = a0;
+  passStruct16BytesHomogeneousFloatx5_a1 = a1;
+  passStruct16BytesHomogeneousFloatx5_a2 = a2;
+  passStruct16BytesHomogeneousFloatx5_a3 = a3;
+  passStruct16BytesHomogeneousFloatx5_a4 = a4;
+
+  final result = passStruct16BytesHomogeneousFloatx5CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct16BytesHomogeneousFloatx5AfterCallback() {
+  final result = passStruct16BytesHomogeneousFloatx5CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct16BytesMixedx10Type = Double Function(
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed);
+
+// Global variables to be able to test inputs after callback returned.
+Struct16BytesMixed passStruct16BytesMixedx10_a0 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a1 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a2 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a3 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a4 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a5 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a6 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a7 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a8 = Struct16BytesMixed();
+Struct16BytesMixed passStruct16BytesMixedx10_a9 = Struct16BytesMixed();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct16BytesMixedx10Result = 0.0;
+
+double passStruct16BytesMixedx10CalculateResult() {
+  double result = 0;
+
+  result += passStruct16BytesMixedx10_a0.a0;
+  result += passStruct16BytesMixedx10_a0.a1;
+  result += passStruct16BytesMixedx10_a1.a0;
+  result += passStruct16BytesMixedx10_a1.a1;
+  result += passStruct16BytesMixedx10_a2.a0;
+  result += passStruct16BytesMixedx10_a2.a1;
+  result += passStruct16BytesMixedx10_a3.a0;
+  result += passStruct16BytesMixedx10_a3.a1;
+  result += passStruct16BytesMixedx10_a4.a0;
+  result += passStruct16BytesMixedx10_a4.a1;
+  result += passStruct16BytesMixedx10_a5.a0;
+  result += passStruct16BytesMixedx10_a5.a1;
+  result += passStruct16BytesMixedx10_a6.a0;
+  result += passStruct16BytesMixedx10_a6.a1;
+  result += passStruct16BytesMixedx10_a7.a0;
+  result += passStruct16BytesMixedx10_a7.a1;
+  result += passStruct16BytesMixedx10_a8.a0;
+  result += passStruct16BytesMixedx10_a8.a1;
+  result += passStruct16BytesMixedx10_a9.a0;
+  result += passStruct16BytesMixedx10_a9.a1;
+
+  passStruct16BytesMixedx10Result = result;
+
+  return result;
+}
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 8 byte aligned.
+double passStruct16BytesMixedx10(
+    Struct16BytesMixed a0,
+    Struct16BytesMixed a1,
+    Struct16BytesMixed a2,
+    Struct16BytesMixed a3,
+    Struct16BytesMixed a4,
+    Struct16BytesMixed a5,
+    Struct16BytesMixed a6,
+    Struct16BytesMixed a7,
+    Struct16BytesMixed a8,
+    Struct16BytesMixed a9) {
+  print(
+      "passStruct16BytesMixedx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct16BytesMixedx10 throwing on purpuse!");
+  }
+
+  passStruct16BytesMixedx10_a0 = a0;
+  passStruct16BytesMixedx10_a1 = a1;
+  passStruct16BytesMixedx10_a2 = a2;
+  passStruct16BytesMixedx10_a3 = a3;
+  passStruct16BytesMixedx10_a4 = a4;
+  passStruct16BytesMixedx10_a5 = a5;
+  passStruct16BytesMixedx10_a6 = a6;
+  passStruct16BytesMixedx10_a7 = a7;
+  passStruct16BytesMixedx10_a8 = a8;
+  passStruct16BytesMixedx10_a9 = a9;
+
+  final result = passStruct16BytesMixedx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct16BytesMixedx10AfterCallback() {
+  final result = passStruct16BytesMixedx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct16BytesMixed2x10Type = Float Function(
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2,
+    Struct16BytesMixed2);
+
+// Global variables to be able to test inputs after callback returned.
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a0 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a1 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a2 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a3 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a4 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a5 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a6 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a7 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a8 = Struct16BytesMixed2();
+Struct16BytesMixed2 passStruct16BytesMixed2x10_a9 = Struct16BytesMixed2();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct16BytesMixed2x10Result = 0.0;
+
+double passStruct16BytesMixed2x10CalculateResult() {
+  double result = 0;
+
+  result += passStruct16BytesMixed2x10_a0.a0;
+  result += passStruct16BytesMixed2x10_a0.a1;
+  result += passStruct16BytesMixed2x10_a0.a2;
+  result += passStruct16BytesMixed2x10_a0.a3;
+  result += passStruct16BytesMixed2x10_a1.a0;
+  result += passStruct16BytesMixed2x10_a1.a1;
+  result += passStruct16BytesMixed2x10_a1.a2;
+  result += passStruct16BytesMixed2x10_a1.a3;
+  result += passStruct16BytesMixed2x10_a2.a0;
+  result += passStruct16BytesMixed2x10_a2.a1;
+  result += passStruct16BytesMixed2x10_a2.a2;
+  result += passStruct16BytesMixed2x10_a2.a3;
+  result += passStruct16BytesMixed2x10_a3.a0;
+  result += passStruct16BytesMixed2x10_a3.a1;
+  result += passStruct16BytesMixed2x10_a3.a2;
+  result += passStruct16BytesMixed2x10_a3.a3;
+  result += passStruct16BytesMixed2x10_a4.a0;
+  result += passStruct16BytesMixed2x10_a4.a1;
+  result += passStruct16BytesMixed2x10_a4.a2;
+  result += passStruct16BytesMixed2x10_a4.a3;
+  result += passStruct16BytesMixed2x10_a5.a0;
+  result += passStruct16BytesMixed2x10_a5.a1;
+  result += passStruct16BytesMixed2x10_a5.a2;
+  result += passStruct16BytesMixed2x10_a5.a3;
+  result += passStruct16BytesMixed2x10_a6.a0;
+  result += passStruct16BytesMixed2x10_a6.a1;
+  result += passStruct16BytesMixed2x10_a6.a2;
+  result += passStruct16BytesMixed2x10_a6.a3;
+  result += passStruct16BytesMixed2x10_a7.a0;
+  result += passStruct16BytesMixed2x10_a7.a1;
+  result += passStruct16BytesMixed2x10_a7.a2;
+  result += passStruct16BytesMixed2x10_a7.a3;
+  result += passStruct16BytesMixed2x10_a8.a0;
+  result += passStruct16BytesMixed2x10_a8.a1;
+  result += passStruct16BytesMixed2x10_a8.a2;
+  result += passStruct16BytesMixed2x10_a8.a3;
+  result += passStruct16BytesMixed2x10_a9.a0;
+  result += passStruct16BytesMixed2x10_a9.a1;
+  result += passStruct16BytesMixed2x10_a9.a2;
+  result += passStruct16BytesMixed2x10_a9.a3;
+
+  passStruct16BytesMixed2x10Result = result;
+
+  return result;
+}
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 4 byte aligned.
+double passStruct16BytesMixed2x10(
+    Struct16BytesMixed2 a0,
+    Struct16BytesMixed2 a1,
+    Struct16BytesMixed2 a2,
+    Struct16BytesMixed2 a3,
+    Struct16BytesMixed2 a4,
+    Struct16BytesMixed2 a5,
+    Struct16BytesMixed2 a6,
+    Struct16BytesMixed2 a7,
+    Struct16BytesMixed2 a8,
+    Struct16BytesMixed2 a9) {
+  print(
+      "passStruct16BytesMixed2x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct16BytesMixed2x10 throwing on purpuse!");
+  }
+
+  passStruct16BytesMixed2x10_a0 = a0;
+  passStruct16BytesMixed2x10_a1 = a1;
+  passStruct16BytesMixed2x10_a2 = a2;
+  passStruct16BytesMixed2x10_a3 = a3;
+  passStruct16BytesMixed2x10_a4 = a4;
+  passStruct16BytesMixed2x10_a5 = a5;
+  passStruct16BytesMixed2x10_a6 = a6;
+  passStruct16BytesMixed2x10_a7 = a7;
+  passStruct16BytesMixed2x10_a8 = a8;
+  passStruct16BytesMixed2x10_a9 = a9;
+
+  final result = passStruct16BytesMixed2x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct16BytesMixed2x10AfterCallback() {
+  final result = passStruct16BytesMixed2x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(20.0, result);
+}
+
+typedef PassStruct17BytesIntx10Type = Int64 Function(
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt,
+    Struct17BytesInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct17BytesInt passStruct17BytesIntx10_a0 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a1 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a2 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a3 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a4 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a5 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a6 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a7 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a8 = Struct17BytesInt();
+Struct17BytesInt passStruct17BytesIntx10_a9 = Struct17BytesInt();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct17BytesIntx10Result = 0;
+
+int passStruct17BytesIntx10CalculateResult() {
+  int result = 0;
+
+  result += passStruct17BytesIntx10_a0.a0;
+  result += passStruct17BytesIntx10_a0.a1;
+  result += passStruct17BytesIntx10_a0.a2;
+  result += passStruct17BytesIntx10_a1.a0;
+  result += passStruct17BytesIntx10_a1.a1;
+  result += passStruct17BytesIntx10_a1.a2;
+  result += passStruct17BytesIntx10_a2.a0;
+  result += passStruct17BytesIntx10_a2.a1;
+  result += passStruct17BytesIntx10_a2.a2;
+  result += passStruct17BytesIntx10_a3.a0;
+  result += passStruct17BytesIntx10_a3.a1;
+  result += passStruct17BytesIntx10_a3.a2;
+  result += passStruct17BytesIntx10_a4.a0;
+  result += passStruct17BytesIntx10_a4.a1;
+  result += passStruct17BytesIntx10_a4.a2;
+  result += passStruct17BytesIntx10_a5.a0;
+  result += passStruct17BytesIntx10_a5.a1;
+  result += passStruct17BytesIntx10_a5.a2;
+  result += passStruct17BytesIntx10_a6.a0;
+  result += passStruct17BytesIntx10_a6.a1;
+  result += passStruct17BytesIntx10_a6.a2;
+  result += passStruct17BytesIntx10_a7.a0;
+  result += passStruct17BytesIntx10_a7.a1;
+  result += passStruct17BytesIntx10_a7.a2;
+  result += passStruct17BytesIntx10_a8.a0;
+  result += passStruct17BytesIntx10_a8.a1;
+  result += passStruct17BytesIntx10_a8.a2;
+  result += passStruct17BytesIntx10_a9.a0;
+  result += passStruct17BytesIntx10_a9.a1;
+  result += passStruct17BytesIntx10_a9.a2;
+
+  passStruct17BytesIntx10Result = result;
+
+  return result;
+}
+
+/// Arguments are passed as pointer to copy on arm64.
+/// Tests that the memory allocated for copies are rounded up to word size.
+int passStruct17BytesIntx10(
+    Struct17BytesInt a0,
+    Struct17BytesInt a1,
+    Struct17BytesInt a2,
+    Struct17BytesInt a3,
+    Struct17BytesInt a4,
+    Struct17BytesInt a5,
+    Struct17BytesInt a6,
+    Struct17BytesInt a7,
+    Struct17BytesInt a8,
+    Struct17BytesInt a9) {
+  print(
+      "passStruct17BytesIntx10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct17BytesIntx10 throwing on purpuse!");
+  }
+
+  passStruct17BytesIntx10_a0 = a0;
+  passStruct17BytesIntx10_a1 = a1;
+  passStruct17BytesIntx10_a2 = a2;
+  passStruct17BytesIntx10_a3 = a3;
+  passStruct17BytesIntx10_a4 = a4;
+  passStruct17BytesIntx10_a5 = a5;
+  passStruct17BytesIntx10_a6 = a6;
+  passStruct17BytesIntx10_a7 = a7;
+  passStruct17BytesIntx10_a8 = a8;
+  passStruct17BytesIntx10_a9 = a9;
+
+  final result = passStruct17BytesIntx10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct17BytesIntx10AfterCallback() {
+  final result = passStruct17BytesIntx10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(15, result);
+}
+
+typedef PassStruct19BytesHomogeneousUint8x10Type = Int64 Function(
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8,
+    Struct19BytesHomogeneousUint8);
+
+// Global variables to be able to test inputs after callback returned.
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a0 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a1 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a2 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a3 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a4 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a5 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a6 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a7 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a8 =
+    Struct19BytesHomogeneousUint8();
+Struct19BytesHomogeneousUint8 passStruct19BytesHomogeneousUint8x10_a9 =
+    Struct19BytesHomogeneousUint8();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct19BytesHomogeneousUint8x10Result = 0;
+
+int passStruct19BytesHomogeneousUint8x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct19BytesHomogeneousUint8x10_a0.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a0.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a1.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a2.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a3.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a4.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a5.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a6.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a7.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a8.a18;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a0;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a1;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a2;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a3;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a4;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a5;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a6;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a7;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a8;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a9;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a10;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a11;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a12;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a13;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a14;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a15;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a16;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a17;
+  result += passStruct19BytesHomogeneousUint8x10_a9.a18;
+
+  passStruct19BytesHomogeneousUint8x10Result = result;
+
+  return result;
+}
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is extended to the right size.
+///
+int passStruct19BytesHomogeneousUint8x10(
+    Struct19BytesHomogeneousUint8 a0,
+    Struct19BytesHomogeneousUint8 a1,
+    Struct19BytesHomogeneousUint8 a2,
+    Struct19BytesHomogeneousUint8 a3,
+    Struct19BytesHomogeneousUint8 a4,
+    Struct19BytesHomogeneousUint8 a5,
+    Struct19BytesHomogeneousUint8 a6,
+    Struct19BytesHomogeneousUint8 a7,
+    Struct19BytesHomogeneousUint8 a8,
+    Struct19BytesHomogeneousUint8 a9) {
+  print(
+      "passStruct19BytesHomogeneousUint8x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct19BytesHomogeneousUint8x10 throwing on purpuse!");
+  }
+
+  passStruct19BytesHomogeneousUint8x10_a0 = a0;
+  passStruct19BytesHomogeneousUint8x10_a1 = a1;
+  passStruct19BytesHomogeneousUint8x10_a2 = a2;
+  passStruct19BytesHomogeneousUint8x10_a3 = a3;
+  passStruct19BytesHomogeneousUint8x10_a4 = a4;
+  passStruct19BytesHomogeneousUint8x10_a5 = a5;
+  passStruct19BytesHomogeneousUint8x10_a6 = a6;
+  passStruct19BytesHomogeneousUint8x10_a7 = a7;
+  passStruct19BytesHomogeneousUint8x10_a8 = a8;
+  passStruct19BytesHomogeneousUint8x10_a9 = a9;
+
+  final result = passStruct19BytesHomogeneousUint8x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct19BytesHomogeneousUint8x10AfterCallback() {
+  final result = passStruct19BytesHomogeneousUint8x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(18145, result);
+}
+
+typedef PassStruct20BytesHomogeneousInt32x10Type = Int32 Function(
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32,
+    Struct20BytesHomogeneousInt32);
+
+// Global variables to be able to test inputs after callback returned.
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a0 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a1 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a2 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a3 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a4 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a5 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a6 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a7 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a8 =
+    Struct20BytesHomogeneousInt32();
+Struct20BytesHomogeneousInt32 passStruct20BytesHomogeneousInt32x10_a9 =
+    Struct20BytesHomogeneousInt32();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct20BytesHomogeneousInt32x10Result = 0;
+
+int passStruct20BytesHomogeneousInt32x10CalculateResult() {
+  int result = 0;
+
+  result += passStruct20BytesHomogeneousInt32x10_a0.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a0.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a1.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a2.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a3.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a4.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a5.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a6.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a7.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a8.a4;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a0;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a1;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a2;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a3;
+  result += passStruct20BytesHomogeneousInt32x10_a9.a4;
+
+  passStruct20BytesHomogeneousInt32x10Result = result;
+
+  return result;
+}
+
+/// Argument too big to go into integer registers on arm64.
+/// The arguments are passed as pointers to copies.
+/// The amount of arguments exhausts the number of integer registers, such that
+/// pointers to copies are also passed on the stack.
+int passStruct20BytesHomogeneousInt32x10(
+    Struct20BytesHomogeneousInt32 a0,
+    Struct20BytesHomogeneousInt32 a1,
+    Struct20BytesHomogeneousInt32 a2,
+    Struct20BytesHomogeneousInt32 a3,
+    Struct20BytesHomogeneousInt32 a4,
+    Struct20BytesHomogeneousInt32 a5,
+    Struct20BytesHomogeneousInt32 a6,
+    Struct20BytesHomogeneousInt32 a7,
+    Struct20BytesHomogeneousInt32 a8,
+    Struct20BytesHomogeneousInt32 a9) {
+  print(
+      "passStruct20BytesHomogeneousInt32x10(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct20BytesHomogeneousInt32x10 throwing on purpuse!");
+  }
+
+  passStruct20BytesHomogeneousInt32x10_a0 = a0;
+  passStruct20BytesHomogeneousInt32x10_a1 = a1;
+  passStruct20BytesHomogeneousInt32x10_a2 = a2;
+  passStruct20BytesHomogeneousInt32x10_a3 = a3;
+  passStruct20BytesHomogeneousInt32x10_a4 = a4;
+  passStruct20BytesHomogeneousInt32x10_a5 = a5;
+  passStruct20BytesHomogeneousInt32x10_a6 = a6;
+  passStruct20BytesHomogeneousInt32x10_a7 = a7;
+  passStruct20BytesHomogeneousInt32x10_a8 = a8;
+  passStruct20BytesHomogeneousInt32x10_a9 = a9;
+
+  final result = passStruct20BytesHomogeneousInt32x10CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct20BytesHomogeneousInt32x10AfterCallback() {
+  final result = passStruct20BytesHomogeneousInt32x10CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(25, result);
+}
+
+typedef PassStruct20BytesHomogeneousFloatType = Float Function(
+    Struct20BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct20BytesHomogeneousFloat passStruct20BytesHomogeneousFloat_a0 =
+    Struct20BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct20BytesHomogeneousFloatResult = 0.0;
+
+double passStruct20BytesHomogeneousFloatCalculateResult() {
+  double result = 0;
+
+  result += passStruct20BytesHomogeneousFloat_a0.a0;
+  result += passStruct20BytesHomogeneousFloat_a0.a1;
+  result += passStruct20BytesHomogeneousFloat_a0.a2;
+  result += passStruct20BytesHomogeneousFloat_a0.a3;
+  result += passStruct20BytesHomogeneousFloat_a0.a4;
+
+  passStruct20BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Argument too big to go into FPU registers in hardfp and arm64.
+double passStruct20BytesHomogeneousFloat(Struct20BytesHomogeneousFloat a0) {
+  print("passStruct20BytesHomogeneousFloat(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct20BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  passStruct20BytesHomogeneousFloat_a0 = a0;
+
+  final result = passStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct20BytesHomogeneousFloatAfterCallback() {
+  final result = passStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-3.0, result);
+}
+
+typedef PassStruct32BytesHomogeneousDoublex5Type = Double Function(
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble,
+    Struct32BytesHomogeneousDouble);
+
+// Global variables to be able to test inputs after callback returned.
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a0 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a1 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a2 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a3 =
+    Struct32BytesHomogeneousDouble();
+Struct32BytesHomogeneousDouble passStruct32BytesHomogeneousDoublex5_a4 =
+    Struct32BytesHomogeneousDouble();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct32BytesHomogeneousDoublex5Result = 0.0;
+
+double passStruct32BytesHomogeneousDoublex5CalculateResult() {
+  double result = 0;
+
+  result += passStruct32BytesHomogeneousDoublex5_a0.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a0.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a0.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a0.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a1.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a2.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a3.a3;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a0;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a1;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a2;
+  result += passStruct32BytesHomogeneousDoublex5_a4.a3;
+
+  passStruct32BytesHomogeneousDoublex5Result = result;
+
+  return result;
+}
+
+/// Arguments in FPU registers on arm64.
+/// 5 struct arguments will exhaust available registers.
+double passStruct32BytesHomogeneousDoublex5(
+    Struct32BytesHomogeneousDouble a0,
+    Struct32BytesHomogeneousDouble a1,
+    Struct32BytesHomogeneousDouble a2,
+    Struct32BytesHomogeneousDouble a3,
+    Struct32BytesHomogeneousDouble a4) {
+  print(
+      "passStruct32BytesHomogeneousDoublex5(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct32BytesHomogeneousDoublex5 throwing on purpuse!");
+  }
+
+  passStruct32BytesHomogeneousDoublex5_a0 = a0;
+  passStruct32BytesHomogeneousDoublex5_a1 = a1;
+  passStruct32BytesHomogeneousDoublex5_a2 = a2;
+  passStruct32BytesHomogeneousDoublex5_a3 = a3;
+  passStruct32BytesHomogeneousDoublex5_a4 = a4;
+
+  final result = passStruct32BytesHomogeneousDoublex5CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct32BytesHomogeneousDoublex5AfterCallback() {
+  final result = passStruct32BytesHomogeneousDoublex5CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(10.0, result);
+}
+
+typedef PassStruct40BytesHomogeneousDoubleType = Double Function(
+    Struct40BytesHomogeneousDouble);
+
+// Global variables to be able to test inputs after callback returned.
+Struct40BytesHomogeneousDouble passStruct40BytesHomogeneousDouble_a0 =
+    Struct40BytesHomogeneousDouble();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct40BytesHomogeneousDoubleResult = 0.0;
+
+double passStruct40BytesHomogeneousDoubleCalculateResult() {
+  double result = 0;
+
+  result += passStruct40BytesHomogeneousDouble_a0.a0;
+  result += passStruct40BytesHomogeneousDouble_a0.a1;
+  result += passStruct40BytesHomogeneousDouble_a0.a2;
+  result += passStruct40BytesHomogeneousDouble_a0.a3;
+  result += passStruct40BytesHomogeneousDouble_a0.a4;
+
+  passStruct40BytesHomogeneousDoubleResult = result;
+
+  return result;
+}
+
+/// Argument too big to go into FPU registers in arm64.
+double passStruct40BytesHomogeneousDouble(Struct40BytesHomogeneousDouble a0) {
+  print("passStruct40BytesHomogeneousDouble(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStruct40BytesHomogeneousDouble throwing on purpuse!");
+  }
+
+  passStruct40BytesHomogeneousDouble_a0 = a0;
+
+  final result = passStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct40BytesHomogeneousDoubleAfterCallback() {
+  final result = passStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-3.0, result);
+}
+
+typedef PassStruct1024BytesHomogeneousUint64Type = Uint64 Function(
+    Struct1024BytesHomogeneousUint64);
+
+// Global variables to be able to test inputs after callback returned.
+Struct1024BytesHomogeneousUint64 passStruct1024BytesHomogeneousUint64_a0 =
+    Struct1024BytesHomogeneousUint64();
+
+// Result variable also global, so we can delete it after the callback.
+int passStruct1024BytesHomogeneousUint64Result = 0;
+
+int passStruct1024BytesHomogeneousUint64CalculateResult() {
+  int result = 0;
+
+  result += passStruct1024BytesHomogeneousUint64_a0.a0;
+  result += passStruct1024BytesHomogeneousUint64_a0.a1;
+  result += passStruct1024BytesHomogeneousUint64_a0.a2;
+  result += passStruct1024BytesHomogeneousUint64_a0.a3;
+  result += passStruct1024BytesHomogeneousUint64_a0.a4;
+  result += passStruct1024BytesHomogeneousUint64_a0.a5;
+  result += passStruct1024BytesHomogeneousUint64_a0.a6;
+  result += passStruct1024BytesHomogeneousUint64_a0.a7;
+  result += passStruct1024BytesHomogeneousUint64_a0.a8;
+  result += passStruct1024BytesHomogeneousUint64_a0.a9;
+  result += passStruct1024BytesHomogeneousUint64_a0.a10;
+  result += passStruct1024BytesHomogeneousUint64_a0.a11;
+  result += passStruct1024BytesHomogeneousUint64_a0.a12;
+  result += passStruct1024BytesHomogeneousUint64_a0.a13;
+  result += passStruct1024BytesHomogeneousUint64_a0.a14;
+  result += passStruct1024BytesHomogeneousUint64_a0.a15;
+  result += passStruct1024BytesHomogeneousUint64_a0.a16;
+  result += passStruct1024BytesHomogeneousUint64_a0.a17;
+  result += passStruct1024BytesHomogeneousUint64_a0.a18;
+  result += passStruct1024BytesHomogeneousUint64_a0.a19;
+  result += passStruct1024BytesHomogeneousUint64_a0.a20;
+  result += passStruct1024BytesHomogeneousUint64_a0.a21;
+  result += passStruct1024BytesHomogeneousUint64_a0.a22;
+  result += passStruct1024BytesHomogeneousUint64_a0.a23;
+  result += passStruct1024BytesHomogeneousUint64_a0.a24;
+  result += passStruct1024BytesHomogeneousUint64_a0.a25;
+  result += passStruct1024BytesHomogeneousUint64_a0.a26;
+  result += passStruct1024BytesHomogeneousUint64_a0.a27;
+  result += passStruct1024BytesHomogeneousUint64_a0.a28;
+  result += passStruct1024BytesHomogeneousUint64_a0.a29;
+  result += passStruct1024BytesHomogeneousUint64_a0.a30;
+  result += passStruct1024BytesHomogeneousUint64_a0.a31;
+  result += passStruct1024BytesHomogeneousUint64_a0.a32;
+  result += passStruct1024BytesHomogeneousUint64_a0.a33;
+  result += passStruct1024BytesHomogeneousUint64_a0.a34;
+  result += passStruct1024BytesHomogeneousUint64_a0.a35;
+  result += passStruct1024BytesHomogeneousUint64_a0.a36;
+  result += passStruct1024BytesHomogeneousUint64_a0.a37;
+  result += passStruct1024BytesHomogeneousUint64_a0.a38;
+  result += passStruct1024BytesHomogeneousUint64_a0.a39;
+  result += passStruct1024BytesHomogeneousUint64_a0.a40;
+  result += passStruct1024BytesHomogeneousUint64_a0.a41;
+  result += passStruct1024BytesHomogeneousUint64_a0.a42;
+  result += passStruct1024BytesHomogeneousUint64_a0.a43;
+  result += passStruct1024BytesHomogeneousUint64_a0.a44;
+  result += passStruct1024BytesHomogeneousUint64_a0.a45;
+  result += passStruct1024BytesHomogeneousUint64_a0.a46;
+  result += passStruct1024BytesHomogeneousUint64_a0.a47;
+  result += passStruct1024BytesHomogeneousUint64_a0.a48;
+  result += passStruct1024BytesHomogeneousUint64_a0.a49;
+  result += passStruct1024BytesHomogeneousUint64_a0.a50;
+  result += passStruct1024BytesHomogeneousUint64_a0.a51;
+  result += passStruct1024BytesHomogeneousUint64_a0.a52;
+  result += passStruct1024BytesHomogeneousUint64_a0.a53;
+  result += passStruct1024BytesHomogeneousUint64_a0.a54;
+  result += passStruct1024BytesHomogeneousUint64_a0.a55;
+  result += passStruct1024BytesHomogeneousUint64_a0.a56;
+  result += passStruct1024BytesHomogeneousUint64_a0.a57;
+  result += passStruct1024BytesHomogeneousUint64_a0.a58;
+  result += passStruct1024BytesHomogeneousUint64_a0.a59;
+  result += passStruct1024BytesHomogeneousUint64_a0.a60;
+  result += passStruct1024BytesHomogeneousUint64_a0.a61;
+  result += passStruct1024BytesHomogeneousUint64_a0.a62;
+  result += passStruct1024BytesHomogeneousUint64_a0.a63;
+  result += passStruct1024BytesHomogeneousUint64_a0.a64;
+  result += passStruct1024BytesHomogeneousUint64_a0.a65;
+  result += passStruct1024BytesHomogeneousUint64_a0.a66;
+  result += passStruct1024BytesHomogeneousUint64_a0.a67;
+  result += passStruct1024BytesHomogeneousUint64_a0.a68;
+  result += passStruct1024BytesHomogeneousUint64_a0.a69;
+  result += passStruct1024BytesHomogeneousUint64_a0.a70;
+  result += passStruct1024BytesHomogeneousUint64_a0.a71;
+  result += passStruct1024BytesHomogeneousUint64_a0.a72;
+  result += passStruct1024BytesHomogeneousUint64_a0.a73;
+  result += passStruct1024BytesHomogeneousUint64_a0.a74;
+  result += passStruct1024BytesHomogeneousUint64_a0.a75;
+  result += passStruct1024BytesHomogeneousUint64_a0.a76;
+  result += passStruct1024BytesHomogeneousUint64_a0.a77;
+  result += passStruct1024BytesHomogeneousUint64_a0.a78;
+  result += passStruct1024BytesHomogeneousUint64_a0.a79;
+  result += passStruct1024BytesHomogeneousUint64_a0.a80;
+  result += passStruct1024BytesHomogeneousUint64_a0.a81;
+  result += passStruct1024BytesHomogeneousUint64_a0.a82;
+  result += passStruct1024BytesHomogeneousUint64_a0.a83;
+  result += passStruct1024BytesHomogeneousUint64_a0.a84;
+  result += passStruct1024BytesHomogeneousUint64_a0.a85;
+  result += passStruct1024BytesHomogeneousUint64_a0.a86;
+  result += passStruct1024BytesHomogeneousUint64_a0.a87;
+  result += passStruct1024BytesHomogeneousUint64_a0.a88;
+  result += passStruct1024BytesHomogeneousUint64_a0.a89;
+  result += passStruct1024BytesHomogeneousUint64_a0.a90;
+  result += passStruct1024BytesHomogeneousUint64_a0.a91;
+  result += passStruct1024BytesHomogeneousUint64_a0.a92;
+  result += passStruct1024BytesHomogeneousUint64_a0.a93;
+  result += passStruct1024BytesHomogeneousUint64_a0.a94;
+  result += passStruct1024BytesHomogeneousUint64_a0.a95;
+  result += passStruct1024BytesHomogeneousUint64_a0.a96;
+  result += passStruct1024BytesHomogeneousUint64_a0.a97;
+  result += passStruct1024BytesHomogeneousUint64_a0.a98;
+  result += passStruct1024BytesHomogeneousUint64_a0.a99;
+  result += passStruct1024BytesHomogeneousUint64_a0.a100;
+  result += passStruct1024BytesHomogeneousUint64_a0.a101;
+  result += passStruct1024BytesHomogeneousUint64_a0.a102;
+  result += passStruct1024BytesHomogeneousUint64_a0.a103;
+  result += passStruct1024BytesHomogeneousUint64_a0.a104;
+  result += passStruct1024BytesHomogeneousUint64_a0.a105;
+  result += passStruct1024BytesHomogeneousUint64_a0.a106;
+  result += passStruct1024BytesHomogeneousUint64_a0.a107;
+  result += passStruct1024BytesHomogeneousUint64_a0.a108;
+  result += passStruct1024BytesHomogeneousUint64_a0.a109;
+  result += passStruct1024BytesHomogeneousUint64_a0.a110;
+  result += passStruct1024BytesHomogeneousUint64_a0.a111;
+  result += passStruct1024BytesHomogeneousUint64_a0.a112;
+  result += passStruct1024BytesHomogeneousUint64_a0.a113;
+  result += passStruct1024BytesHomogeneousUint64_a0.a114;
+  result += passStruct1024BytesHomogeneousUint64_a0.a115;
+  result += passStruct1024BytesHomogeneousUint64_a0.a116;
+  result += passStruct1024BytesHomogeneousUint64_a0.a117;
+  result += passStruct1024BytesHomogeneousUint64_a0.a118;
+  result += passStruct1024BytesHomogeneousUint64_a0.a119;
+  result += passStruct1024BytesHomogeneousUint64_a0.a120;
+  result += passStruct1024BytesHomogeneousUint64_a0.a121;
+  result += passStruct1024BytesHomogeneousUint64_a0.a122;
+  result += passStruct1024BytesHomogeneousUint64_a0.a123;
+  result += passStruct1024BytesHomogeneousUint64_a0.a124;
+  result += passStruct1024BytesHomogeneousUint64_a0.a125;
+  result += passStruct1024BytesHomogeneousUint64_a0.a126;
+  result += passStruct1024BytesHomogeneousUint64_a0.a127;
+
+  passStruct1024BytesHomogeneousUint64Result = result;
+
+  return result;
+}
+
+/// Test 1kb struct.
+int passStruct1024BytesHomogeneousUint64(Struct1024BytesHomogeneousUint64 a0) {
+  print("passStruct1024BytesHomogeneousUint64(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct1024BytesHomogeneousUint64 throwing on purpuse!");
+  }
+
+  passStruct1024BytesHomogeneousUint64_a0 = a0;
+
+  final result = passStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct1024BytesHomogeneousUint64AfterCallback() {
+  final result = passStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(8256, result);
+}
+
+typedef PassFloatStruct16BytesHomogeneousFloatFloatStruct1Type = Float Function(
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float,
+    Struct16BytesHomogeneousFloat,
+    Float);
+
+// Global variables to be able to test inputs after callback returned.
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a0 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a2 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a4 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a6 = 0.0;
+Struct16BytesHomogeneousFloat
+    passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7 =
+    Struct16BytesHomogeneousFloat();
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1_a8 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1Result = 0.0;
+
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1CalculateResult() {
+  double result = 0;
+
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a4;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a6;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a0;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a1;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a2;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7.a3;
+  result += passFloatStruct16BytesHomogeneousFloatFloatStruct1_a8;
+
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1Result = result;
+
+  return result;
+}
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+double passFloatStruct16BytesHomogeneousFloatFloatStruct1(
+    double a0,
+    Struct16BytesHomogeneousFloat a1,
+    double a2,
+    Struct16BytesHomogeneousFloat a3,
+    double a4,
+    Struct16BytesHomogeneousFloat a5,
+    double a6,
+    Struct16BytesHomogeneousFloat a7,
+    double a8) {
+  print(
+      "passFloatStruct16BytesHomogeneousFloatFloatStruct1(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassFloatStruct16BytesHomogeneousFloatFloatStruct1 throwing on purpuse!");
+  }
+
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a0 = a0;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a1 = a1;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a2 = a2;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a3 = a3;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a4 = a4;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a5 = a5;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a6 = a6;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a7 = a7;
+  passFloatStruct16BytesHomogeneousFloatFloatStruct1_a8 = a8;
+
+  final result =
+      passFloatStruct16BytesHomogeneousFloatFloatStruct1CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passFloatStruct16BytesHomogeneousFloatFloatStruct1AfterCallback() {
+  final result =
+      passFloatStruct16BytesHomogeneousFloatFloatStruct1CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-11.0, result);
+}
+
+typedef PassFloatStruct32BytesHomogeneousDoubleFloatStructType
+    = Double Function(
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float,
+        Struct32BytesHomogeneousDouble,
+        Float);
+
+// Global variables to be able to test inputs after callback returned.
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a0 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a2 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a4 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a6 = 0.0;
+Struct32BytesHomogeneousDouble
+    passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7 =
+    Struct32BytesHomogeneousDouble();
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct_a8 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+double passFloatStruct32BytesHomogeneousDoubleFloatStructResult = 0.0;
+
+double passFloatStruct32BytesHomogeneousDoubleFloatStructCalculateResult() {
+  double result = 0;
+
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a4;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a6;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a0;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a1;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a2;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7.a3;
+  result += passFloatStruct32BytesHomogeneousDoubleFloatStruct_a8;
+
+  passFloatStruct32BytesHomogeneousDoubleFloatStructResult = result;
+
+  return result;
+}
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+double passFloatStruct32BytesHomogeneousDoubleFloatStruct(
+    double a0,
+    Struct32BytesHomogeneousDouble a1,
+    double a2,
+    Struct32BytesHomogeneousDouble a3,
+    double a4,
+    Struct32BytesHomogeneousDouble a5,
+    double a6,
+    Struct32BytesHomogeneousDouble a7,
+    double a8) {
+  print(
+      "passFloatStruct32BytesHomogeneousDoubleFloatStruct(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassFloatStruct32BytesHomogeneousDoubleFloatStruct throwing on purpuse!");
+  }
+
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a0 = a0;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a1 = a1;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a2 = a2;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a3 = a3;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a4 = a4;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a5 = a5;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a6 = a6;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a7 = a7;
+  passFloatStruct32BytesHomogeneousDoubleFloatStruct_a8 = a8;
+
+  final result =
+      passFloatStruct32BytesHomogeneousDoubleFloatStructCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passFloatStruct32BytesHomogeneousDoubleFloatStructAfterCallback() {
+  final result =
+      passFloatStruct32BytesHomogeneousDoubleFloatStructCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-11.0, result);
+}
+
+typedef PassInt8Struct16BytesMixedInt8Struct16BytesMixedInType
+    = Double Function(Int8, Struct16BytesMixed, Int8, Struct16BytesMixed, Int8,
+        Struct16BytesMixed, Int8, Struct16BytesMixed, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a0 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a2 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a4 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a6 = 0;
+Struct16BytesMixed passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7 =
+    Struct16BytesMixed();
+int passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a8 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+double passInt8Struct16BytesMixedInt8Struct16BytesMixedInResult = 0.0;
+
+double passInt8Struct16BytesMixedInt8Struct16BytesMixedInCalculateResult() {
+  double result = 0;
+
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a2;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a4;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a6;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7.a0;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7.a1;
+  result += passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a8;
+
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedInResult = result;
+
+  return result;
+}
+
+/// Tests the alignment of structs in integers registers and on the stack.
+/// Arm32 aligns this struct at 8.
+/// Also, arm32 allocates the second struct partially in registers, partially
+/// on stack.
+/// Test backfilling of integer registers.
+double passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
+    int a0,
+    Struct16BytesMixed a1,
+    int a2,
+    Struct16BytesMixed a3,
+    int a4,
+    Struct16BytesMixed a5,
+    int a6,
+    Struct16BytesMixed a7,
+    int a8) {
+  print(
+      "passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn throwing on purpuse!");
+  }
+
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a0 = a0;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a1 = a1;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a2 = a2;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a3 = a3;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a4 = a4;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a5 = a5;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a6 = a6;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a7 = a7;
+  passInt8Struct16BytesMixedInt8Struct16BytesMixedIn_a8 = a8;
+
+  final result =
+      passInt8Struct16BytesMixedInt8Struct16BytesMixedInCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passInt8Struct16BytesMixedInt8Struct16BytesMixedInAfterCallback() {
+  final result =
+      passInt8Struct16BytesMixedInt8Struct16BytesMixedInCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-7.0, result);
+}
+
+typedef PassDoublex6Struct16BytesMixedx4Int32Type = Double Function(
+    Double,
+    Double,
+    Double,
+    Double,
+    Double,
+    Double,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Int32);
+
+// Global variables to be able to test inputs after callback returned.
+double passDoublex6Struct16BytesMixedx4Int32_a0 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a1 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a2 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a3 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a4 = 0.0;
+double passDoublex6Struct16BytesMixedx4Int32_a5 = 0.0;
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a6 =
+    Struct16BytesMixed();
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a7 =
+    Struct16BytesMixed();
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a8 =
+    Struct16BytesMixed();
+Struct16BytesMixed passDoublex6Struct16BytesMixedx4Int32_a9 =
+    Struct16BytesMixed();
+int passDoublex6Struct16BytesMixedx4Int32_a10 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+double passDoublex6Struct16BytesMixedx4Int32Result = 0.0;
+
+double passDoublex6Struct16BytesMixedx4Int32CalculateResult() {
+  double result = 0;
+
+  result += passDoublex6Struct16BytesMixedx4Int32_a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a2;
+  result += passDoublex6Struct16BytesMixedx4Int32_a3;
+  result += passDoublex6Struct16BytesMixedx4Int32_a4;
+  result += passDoublex6Struct16BytesMixedx4Int32_a5;
+  result += passDoublex6Struct16BytesMixedx4Int32_a6.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a6.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a7.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a7.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a8.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a8.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a9.a0;
+  result += passDoublex6Struct16BytesMixedx4Int32_a9.a1;
+  result += passDoublex6Struct16BytesMixedx4Int32_a10;
+
+  passDoublex6Struct16BytesMixedx4Int32Result = result;
+
+  return result;
+}
+
+/// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+/// structs. The rest of the structs will go on the stack.
+/// The int will be backfilled into the int register.
+double passDoublex6Struct16BytesMixedx4Int32(
+    double a0,
+    double a1,
+    double a2,
+    double a3,
+    double a4,
+    double a5,
+    Struct16BytesMixed a6,
+    Struct16BytesMixed a7,
+    Struct16BytesMixed a8,
+    Struct16BytesMixed a9,
+    int a10) {
+  print(
+      "passDoublex6Struct16BytesMixedx4Int32(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassDoublex6Struct16BytesMixedx4Int32 throwing on purpuse!");
+  }
+
+  passDoublex6Struct16BytesMixedx4Int32_a0 = a0;
+  passDoublex6Struct16BytesMixedx4Int32_a1 = a1;
+  passDoublex6Struct16BytesMixedx4Int32_a2 = a2;
+  passDoublex6Struct16BytesMixedx4Int32_a3 = a3;
+  passDoublex6Struct16BytesMixedx4Int32_a4 = a4;
+  passDoublex6Struct16BytesMixedx4Int32_a5 = a5;
+  passDoublex6Struct16BytesMixedx4Int32_a6 = a6;
+  passDoublex6Struct16BytesMixedx4Int32_a7 = a7;
+  passDoublex6Struct16BytesMixedx4Int32_a8 = a8;
+  passDoublex6Struct16BytesMixedx4Int32_a9 = a9;
+  passDoublex6Struct16BytesMixedx4Int32_a10 = a10;
+
+  final result = passDoublex6Struct16BytesMixedx4Int32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passDoublex6Struct16BytesMixedx4Int32AfterCallback() {
+  final result = passDoublex6Struct16BytesMixedx4Int32CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-8.0, result);
+}
+
+typedef PassInt32x4Struct16BytesMixedx4DoubleType = Double Function(
+    Int32,
+    Int32,
+    Int32,
+    Int32,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Struct16BytesMixed,
+    Double);
+
+// Global variables to be able to test inputs after callback returned.
+int passInt32x4Struct16BytesMixedx4Double_a0 = 0;
+int passInt32x4Struct16BytesMixedx4Double_a1 = 0;
+int passInt32x4Struct16BytesMixedx4Double_a2 = 0;
+int passInt32x4Struct16BytesMixedx4Double_a3 = 0;
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a4 =
+    Struct16BytesMixed();
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a5 =
+    Struct16BytesMixed();
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a6 =
+    Struct16BytesMixed();
+Struct16BytesMixed passInt32x4Struct16BytesMixedx4Double_a7 =
+    Struct16BytesMixed();
+double passInt32x4Struct16BytesMixedx4Double_a8 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+double passInt32x4Struct16BytesMixedx4DoubleResult = 0.0;
+
+double passInt32x4Struct16BytesMixedx4DoubleCalculateResult() {
+  double result = 0;
+
+  result += passInt32x4Struct16BytesMixedx4Double_a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a2;
+  result += passInt32x4Struct16BytesMixedx4Double_a3;
+  result += passInt32x4Struct16BytesMixedx4Double_a4.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a4.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a5.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a5.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a6.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a6.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a7.a0;
+  result += passInt32x4Struct16BytesMixedx4Double_a7.a1;
+  result += passInt32x4Struct16BytesMixedx4Double_a8;
+
+  passInt32x4Struct16BytesMixedx4DoubleResult = result;
+
+  return result;
+}
+
+/// On Linux x64, it will exhaust int registers first.
+/// The rest of the structs will go on the stack.
+/// The double will be backfilled into the xmm register.
+double passInt32x4Struct16BytesMixedx4Double(
+    int a0,
+    int a1,
+    int a2,
+    int a3,
+    Struct16BytesMixed a4,
+    Struct16BytesMixed a5,
+    Struct16BytesMixed a6,
+    Struct16BytesMixed a7,
+    double a8) {
+  print(
+      "passInt32x4Struct16BytesMixedx4Double(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassInt32x4Struct16BytesMixedx4Double throwing on purpuse!");
+  }
+
+  passInt32x4Struct16BytesMixedx4Double_a0 = a0;
+  passInt32x4Struct16BytesMixedx4Double_a1 = a1;
+  passInt32x4Struct16BytesMixedx4Double_a2 = a2;
+  passInt32x4Struct16BytesMixedx4Double_a3 = a3;
+  passInt32x4Struct16BytesMixedx4Double_a4 = a4;
+  passInt32x4Struct16BytesMixedx4Double_a5 = a5;
+  passInt32x4Struct16BytesMixedx4Double_a6 = a6;
+  passInt32x4Struct16BytesMixedx4Double_a7 = a7;
+  passInt32x4Struct16BytesMixedx4Double_a8 = a8;
+
+  final result = passInt32x4Struct16BytesMixedx4DoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passInt32x4Struct16BytesMixedx4DoubleAfterCallback() {
+  final result = passInt32x4Struct16BytesMixedx4DoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-7.0, result);
+}
+
+typedef PassStruct40BytesHomogeneousDoubleStruct4BytesHomoType
+    = Double Function(Struct40BytesHomogeneousDouble,
+        Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct40BytesHomogeneousDouble
+    passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0 =
+    Struct40BytesHomogeneousDouble();
+Struct4BytesHomogeneousInt16
+    passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1 =
+    Struct4BytesHomogeneousInt16();
+Struct8BytesHomogeneousFloat
+    passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2 =
+    Struct8BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+double passStruct40BytesHomogeneousDoubleStruct4BytesHomoResult = 0.0;
+
+double passStruct40BytesHomogeneousDoubleStruct4BytesHomoCalculateResult() {
+  double result = 0;
+
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a0;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a1;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a2;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a3;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0.a4;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1.a0;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1.a1;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2.a0;
+  result += passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2.a1;
+
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomoResult = result;
+
+  return result;
+}
+
+/// On various architectures, first struct is allocated on stack.
+/// Check that the other two arguments are allocated on registers.
+double passStruct40BytesHomogeneousDoubleStruct4BytesHomo(
+    Struct40BytesHomogeneousDouble a0,
+    Struct4BytesHomogeneousInt16 a1,
+    Struct8BytesHomogeneousFloat a2) {
+  print(
+      "passStruct40BytesHomogeneousDoubleStruct4BytesHomo(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo throwing on purpuse!");
+  }
+
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a0 = a0;
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a1 = a1;
+  passStruct40BytesHomogeneousDoubleStruct4BytesHomo_a2 = a2;
+
+  final result =
+      passStruct40BytesHomogeneousDoubleStruct4BytesHomoCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStruct40BytesHomogeneousDoubleStruct4BytesHomoAfterCallback() {
+  final result =
+      passStruct40BytesHomogeneousDoubleStruct4BytesHomoCalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.approxEquals(-5.0, result);
+}
+
+typedef PassStructAlignmentInt16Type = Int64 Function(StructAlignmentInt16);
+
+// Global variables to be able to test inputs after callback returned.
+StructAlignmentInt16 passStructAlignmentInt16_a0 = StructAlignmentInt16();
+
+// Result variable also global, so we can delete it after the callback.
+int passStructAlignmentInt16Result = 0;
+
+int passStructAlignmentInt16CalculateResult() {
+  int result = 0;
+
+  result += passStructAlignmentInt16_a0.a0;
+  result += passStructAlignmentInt16_a0.a1;
+  result += passStructAlignmentInt16_a0.a2;
+
+  passStructAlignmentInt16Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 16 byte int within struct.
+int passStructAlignmentInt16(StructAlignmentInt16 a0) {
+  print("passStructAlignmentInt16(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStructAlignmentInt16 throwing on purpuse!");
+  }
+
+  passStructAlignmentInt16_a0 = a0;
+
+  final result = passStructAlignmentInt16CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructAlignmentInt16AfterCallback() {
+  final result = passStructAlignmentInt16CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(-2, result);
+}
+
+typedef PassStructAlignmentInt32Type = Int64 Function(StructAlignmentInt32);
+
+// Global variables to be able to test inputs after callback returned.
+StructAlignmentInt32 passStructAlignmentInt32_a0 = StructAlignmentInt32();
+
+// Result variable also global, so we can delete it after the callback.
+int passStructAlignmentInt32Result = 0;
+
+int passStructAlignmentInt32CalculateResult() {
+  int result = 0;
+
+  result += passStructAlignmentInt32_a0.a0;
+  result += passStructAlignmentInt32_a0.a1;
+  result += passStructAlignmentInt32_a0.a2;
+
+  passStructAlignmentInt32Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 32 byte int within struct.
+int passStructAlignmentInt32(StructAlignmentInt32 a0) {
+  print("passStructAlignmentInt32(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStructAlignmentInt32 throwing on purpuse!");
+  }
+
+  passStructAlignmentInt32_a0 = a0;
+
+  final result = passStructAlignmentInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructAlignmentInt32AfterCallback() {
+  final result = passStructAlignmentInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(-2, result);
+}
+
+typedef PassStructAlignmentInt64Type = Int64 Function(StructAlignmentInt64);
+
+// Global variables to be able to test inputs after callback returned.
+StructAlignmentInt64 passStructAlignmentInt64_a0 = StructAlignmentInt64();
+
+// Result variable also global, so we can delete it after the callback.
+int passStructAlignmentInt64Result = 0;
+
+int passStructAlignmentInt64CalculateResult() {
+  int result = 0;
+
+  result += passStructAlignmentInt64_a0.a0;
+  result += passStructAlignmentInt64_a0.a1;
+  result += passStructAlignmentInt64_a0.a2;
+
+  passStructAlignmentInt64Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 64 byte int within struct.
+int passStructAlignmentInt64(StructAlignmentInt64 a0) {
+  print("passStructAlignmentInt64(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("PassStructAlignmentInt64 throwing on purpuse!");
+  }
+
+  passStructAlignmentInt64_a0 = a0;
+
+  final result = passStructAlignmentInt64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void passStructAlignmentInt64AfterCallback() {
+  final result = passStructAlignmentInt64CalculateResult();
+
+  print("after callback result = $result");
+
+  Expect.equals(-2, result);
+}
+
+typedef ReturnStruct1ByteIntType = Struct1ByteInt Function(Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct1ByteInt_a0 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct1ByteInt returnStruct1ByteIntResult = Struct1ByteInt();
+
+Struct1ByteInt returnStruct1ByteIntCalculateResult() {
+  Struct1ByteInt result = allocate<Struct1ByteInt>().ref;
+
+  result.a0 = returnStruct1ByteInt_a0;
+
+  returnStruct1ByteIntResult = result;
+
+  return result;
+}
+
+/// Smallest struct with data.
+Struct1ByteInt returnStruct1ByteInt(int a0) {
+  print("returnStruct1ByteInt(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct1ByteInt throwing on purpuse!");
+  }
+
+  returnStruct1ByteInt_a0 = a0;
+
+  final result = returnStruct1ByteIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct1ByteIntAfterCallback() {
+  free(returnStruct1ByteIntResult.addressOf);
+
+  final result = returnStruct1ByteIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct1ByteIntResult.addressOf);
+}
+
+typedef ReturnStruct3BytesIntType = Struct3BytesInt Function(Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct3BytesInt_a0 = 0;
+int returnStruct3BytesInt_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct3BytesInt returnStruct3BytesIntResult = Struct3BytesInt();
+
+Struct3BytesInt returnStruct3BytesIntCalculateResult() {
+  Struct3BytesInt result = allocate<Struct3BytesInt>().ref;
+
+  result.a0 = returnStruct3BytesInt_a0;
+  result.a1 = returnStruct3BytesInt_a1;
+
+  returnStruct3BytesIntResult = result;
+
+  return result;
+}
+
+/// Smaller than word size return value on all architectures.
+Struct3BytesInt returnStruct3BytesInt(int a0, int a1) {
+  print("returnStruct3BytesInt(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct3BytesInt throwing on purpuse!");
+  }
+
+  returnStruct3BytesInt_a0 = a0;
+  returnStruct3BytesInt_a1 = a1;
+
+  final result = returnStruct3BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct3BytesIntAfterCallback() {
+  free(returnStruct3BytesIntResult.addressOf);
+
+  final result = returnStruct3BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct3BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct4BytesHomogeneousInt16Type = Struct4BytesHomogeneousInt16
+    Function(Int16, Int16);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct4BytesHomogeneousInt16_a0 = 0;
+int returnStruct4BytesHomogeneousInt16_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct4BytesHomogeneousInt16 returnStruct4BytesHomogeneousInt16Result =
+    Struct4BytesHomogeneousInt16();
+
+Struct4BytesHomogeneousInt16
+    returnStruct4BytesHomogeneousInt16CalculateResult() {
+  Struct4BytesHomogeneousInt16 result =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+
+  result.a0 = returnStruct4BytesHomogeneousInt16_a0;
+  result.a1 = returnStruct4BytesHomogeneousInt16_a1;
+
+  returnStruct4BytesHomogeneousInt16Result = result;
+
+  return result;
+}
+
+/// Word size return value on 32 bit architectures..
+Struct4BytesHomogeneousInt16 returnStruct4BytesHomogeneousInt16(
+    int a0, int a1) {
+  print("returnStruct4BytesHomogeneousInt16(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct4BytesHomogeneousInt16 throwing on purpuse!");
+  }
+
+  returnStruct4BytesHomogeneousInt16_a0 = a0;
+  returnStruct4BytesHomogeneousInt16_a1 = a1;
+
+  final result = returnStruct4BytesHomogeneousInt16CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct4BytesHomogeneousInt16AfterCallback() {
+  free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+
+  final result = returnStruct4BytesHomogeneousInt16CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct4BytesHomogeneousInt16Result.addressOf);
+}
+
+typedef ReturnStruct7BytesIntType = Struct7BytesInt Function(
+    Int32, Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct7BytesInt_a0 = 0;
+int returnStruct7BytesInt_a1 = 0;
+int returnStruct7BytesInt_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct7BytesInt returnStruct7BytesIntResult = Struct7BytesInt();
+
+Struct7BytesInt returnStruct7BytesIntCalculateResult() {
+  Struct7BytesInt result = allocate<Struct7BytesInt>().ref;
+
+  result.a0 = returnStruct7BytesInt_a0;
+  result.a1 = returnStruct7BytesInt_a1;
+  result.a2 = returnStruct7BytesInt_a2;
+
+  returnStruct7BytesIntResult = result;
+
+  return result;
+}
+
+/// Non-wordsize return value.
+Struct7BytesInt returnStruct7BytesInt(int a0, int a1, int a2) {
+  print("returnStruct7BytesInt(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct7BytesInt throwing on purpuse!");
+  }
+
+  returnStruct7BytesInt_a0 = a0;
+  returnStruct7BytesInt_a1 = a1;
+  returnStruct7BytesInt_a2 = a2;
+
+  final result = returnStruct7BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct7BytesIntAfterCallback() {
+  free(returnStruct7BytesIntResult.addressOf);
+
+  final result = returnStruct7BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct7BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct8BytesIntType = Struct8BytesInt Function(
+    Int16, Int16, Int32);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct8BytesInt_a0 = 0;
+int returnStruct8BytesInt_a1 = 0;
+int returnStruct8BytesInt_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesInt returnStruct8BytesIntResult = Struct8BytesInt();
+
+Struct8BytesInt returnStruct8BytesIntCalculateResult() {
+  Struct8BytesInt result = allocate<Struct8BytesInt>().ref;
+
+  result.a0 = returnStruct8BytesInt_a0;
+  result.a1 = returnStruct8BytesInt_a1;
+  result.a2 = returnStruct8BytesInt_a2;
+
+  returnStruct8BytesIntResult = result;
+
+  return result;
+}
+
+/// Return value in integer registers on many architectures.
+Struct8BytesInt returnStruct8BytesInt(int a0, int a1, int a2) {
+  print("returnStruct8BytesInt(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesInt throwing on purpuse!");
+  }
+
+  returnStruct8BytesInt_a0 = a0;
+  returnStruct8BytesInt_a1 = a1;
+  returnStruct8BytesInt_a2 = a2;
+
+  final result = returnStruct8BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesIntAfterCallback() {
+  free(returnStruct8BytesIntResult.addressOf);
+
+  final result = returnStruct8BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct8BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct8BytesHomogeneousFloatType = Struct8BytesHomogeneousFloat
+    Function(Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct8BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct8BytesHomogeneousFloat_a1 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesHomogeneousFloat returnStruct8BytesHomogeneousFloatResult =
+    Struct8BytesHomogeneousFloat();
+
+Struct8BytesHomogeneousFloat
+    returnStruct8BytesHomogeneousFloatCalculateResult() {
+  Struct8BytesHomogeneousFloat result =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct8BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct8BytesHomogeneousFloat_a1;
+
+  returnStruct8BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value in FP registers on many architectures.
+Struct8BytesHomogeneousFloat returnStruct8BytesHomogeneousFloat(
+    double a0, double a1) {
+  print("returnStruct8BytesHomogeneousFloat(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct8BytesHomogeneousFloat_a0 = a0;
+  returnStruct8BytesHomogeneousFloat_a1 = a1;
+
+  final result = returnStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct8BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct8BytesMixedType = Struct8BytesMixed Function(
+    Float, Int16, Int16);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct8BytesMixed_a0 = 0.0;
+int returnStruct8BytesMixed_a1 = 0;
+int returnStruct8BytesMixed_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesMixed returnStruct8BytesMixedResult = Struct8BytesMixed();
+
+Struct8BytesMixed returnStruct8BytesMixedCalculateResult() {
+  Struct8BytesMixed result = allocate<Struct8BytesMixed>().ref;
+
+  result.a0 = returnStruct8BytesMixed_a0;
+  result.a1 = returnStruct8BytesMixed_a1;
+  result.a2 = returnStruct8BytesMixed_a2;
+
+  returnStruct8BytesMixedResult = result;
+
+  return result;
+}
+
+/// Return value split over FP and integer register in x64.
+Struct8BytesMixed returnStruct8BytesMixed(double a0, int a1, int a2) {
+  print("returnStruct8BytesMixed(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct8BytesMixed throwing on purpuse!");
+  }
+
+  returnStruct8BytesMixed_a0 = a0;
+  returnStruct8BytesMixed_a1 = a1;
+  returnStruct8BytesMixed_a2 = a2;
+
+  final result = returnStruct8BytesMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct8BytesMixedAfterCallback() {
+  free(returnStruct8BytesMixedResult.addressOf);
+
+  final result = returnStruct8BytesMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct8BytesMixedResult.addressOf);
+}
+
+typedef ReturnStruct9BytesIntType = Struct9BytesInt Function(Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesInt_a0 = 0;
+int returnStruct9BytesInt_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct9BytesInt returnStruct9BytesIntResult = Struct9BytesInt();
+
+Struct9BytesInt returnStruct9BytesIntCalculateResult() {
+  Struct9BytesInt result = allocate<Struct9BytesInt>().ref;
+
+  result.a0 = returnStruct9BytesInt_a0;
+  result.a1 = returnStruct9BytesInt_a1;
+
+  returnStruct9BytesIntResult = result;
+
+  return result;
+}
+
+/// Return value in two integer registers on x64.
+/// The second register only contains a single byte.
+Struct9BytesInt returnStruct9BytesInt(int a0, int a1) {
+  print("returnStruct9BytesInt(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct9BytesInt throwing on purpuse!");
+  }
+
+  returnStruct9BytesInt_a0 = a0;
+  returnStruct9BytesInt_a1 = a1;
+
+  final result = returnStruct9BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesIntAfterCallback() {
+  free(returnStruct9BytesIntResult.addressOf);
+
+  final result = returnStruct9BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct9BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct9BytesHomogeneousUint82Type = Struct9BytesHomogeneousUint82
+    Function(Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct9BytesHomogeneousUint82_a0 = 0;
+int returnStruct9BytesHomogeneousUint82_a1 = 0;
+int returnStruct9BytesHomogeneousUint82_a2 = 0;
+int returnStruct9BytesHomogeneousUint82_a3 = 0;
+int returnStruct9BytesHomogeneousUint82_a4 = 0;
+int returnStruct9BytesHomogeneousUint82_a5 = 0;
+int returnStruct9BytesHomogeneousUint82_a6 = 0;
+int returnStruct9BytesHomogeneousUint82_a7 = 0;
+int returnStruct9BytesHomogeneousUint82_a8 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82Result =
+    Struct9BytesHomogeneousUint82();
+
+Struct9BytesHomogeneousUint82
+    returnStruct9BytesHomogeneousUint82CalculateResult() {
+  Struct9BytesHomogeneousUint82 result =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+
+  result.a0 = returnStruct9BytesHomogeneousUint82_a0;
+  result.a1 = returnStruct9BytesHomogeneousUint82_a1;
+  result.a2 = returnStruct9BytesHomogeneousUint82_a2;
+  result.a3 = returnStruct9BytesHomogeneousUint82_a3;
+  result.a4 = returnStruct9BytesHomogeneousUint82_a4;
+  result.a5 = returnStruct9BytesHomogeneousUint82_a5;
+  result.a6 = returnStruct9BytesHomogeneousUint82_a6;
+  result.a7 = returnStruct9BytesHomogeneousUint82_a7;
+  result.a8 = returnStruct9BytesHomogeneousUint82_a8;
+
+  returnStruct9BytesHomogeneousUint82Result = result;
+
+  return result;
+}
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+Struct9BytesHomogeneousUint82 returnStruct9BytesHomogeneousUint82(
+    int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) {
+  print(
+      "returnStruct9BytesHomogeneousUint82(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct9BytesHomogeneousUint82 throwing on purpuse!");
+  }
+
+  returnStruct9BytesHomogeneousUint82_a0 = a0;
+  returnStruct9BytesHomogeneousUint82_a1 = a1;
+  returnStruct9BytesHomogeneousUint82_a2 = a2;
+  returnStruct9BytesHomogeneousUint82_a3 = a3;
+  returnStruct9BytesHomogeneousUint82_a4 = a4;
+  returnStruct9BytesHomogeneousUint82_a5 = a5;
+  returnStruct9BytesHomogeneousUint82_a6 = a6;
+  returnStruct9BytesHomogeneousUint82_a7 = a7;
+  returnStruct9BytesHomogeneousUint82_a8 = a8;
+
+  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct9BytesHomogeneousUint82AfterCallback() {
+  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+
+  final result = returnStruct9BytesHomogeneousUint82CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct9BytesHomogeneousUint82Result.addressOf);
+}
+
+typedef ReturnStruct12BytesHomogeneousFloatType = Struct12BytesHomogeneousFloat
+    Function(Float, Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct12BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct12BytesHomogeneousFloat_a1 = 0.0;
+double returnStruct12BytesHomogeneousFloat_a2 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct12BytesHomogeneousFloat returnStruct12BytesHomogeneousFloatResult =
+    Struct12BytesHomogeneousFloat();
+
+Struct12BytesHomogeneousFloat
+    returnStruct12BytesHomogeneousFloatCalculateResult() {
+  Struct12BytesHomogeneousFloat result =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct12BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct12BytesHomogeneousFloat_a1;
+  result.a2 = returnStruct12BytesHomogeneousFloat_a2;
+
+  returnStruct12BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value in FPU registers, but does not use all registers on arm hardfp
+/// and arm64.
+Struct12BytesHomogeneousFloat returnStruct12BytesHomogeneousFloat(
+    double a0, double a1, double a2) {
+  print("returnStruct12BytesHomogeneousFloat(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct12BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct12BytesHomogeneousFloat_a0 = a0;
+  returnStruct12BytesHomogeneousFloat_a1 = a1;
+  returnStruct12BytesHomogeneousFloat_a2 = a2;
+
+  final result = returnStruct12BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct12BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct12BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct12BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct16BytesHomogeneousFloatType = Struct16BytesHomogeneousFloat
+    Function(Float, Float, Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct16BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct16BytesHomogeneousFloat_a1 = 0.0;
+double returnStruct16BytesHomogeneousFloat_a2 = 0.0;
+double returnStruct16BytesHomogeneousFloat_a3 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct16BytesHomogeneousFloat returnStruct16BytesHomogeneousFloatResult =
+    Struct16BytesHomogeneousFloat();
+
+Struct16BytesHomogeneousFloat
+    returnStruct16BytesHomogeneousFloatCalculateResult() {
+  Struct16BytesHomogeneousFloat result =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct16BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct16BytesHomogeneousFloat_a1;
+  result.a2 = returnStruct16BytesHomogeneousFloat_a2;
+  result.a3 = returnStruct16BytesHomogeneousFloat_a3;
+
+  returnStruct16BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value in FPU registers on arm hardfp and arm64.
+Struct16BytesHomogeneousFloat returnStruct16BytesHomogeneousFloat(
+    double a0, double a1, double a2, double a3) {
+  print("returnStruct16BytesHomogeneousFloat(${a0}, ${a1}, ${a2}, ${a3})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct16BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct16BytesHomogeneousFloat_a0 = a0;
+  returnStruct16BytesHomogeneousFloat_a1 = a1;
+  returnStruct16BytesHomogeneousFloat_a2 = a2;
+  returnStruct16BytesHomogeneousFloat_a3 = a3;
+
+  final result = returnStruct16BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct16BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct16BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct16BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct16BytesMixedType = Struct16BytesMixed Function(
+    Double, Int64);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct16BytesMixed_a0 = 0.0;
+int returnStruct16BytesMixed_a1 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct16BytesMixed returnStruct16BytesMixedResult = Struct16BytesMixed();
+
+Struct16BytesMixed returnStruct16BytesMixedCalculateResult() {
+  Struct16BytesMixed result = allocate<Struct16BytesMixed>().ref;
+
+  result.a0 = returnStruct16BytesMixed_a0;
+  result.a1 = returnStruct16BytesMixed_a1;
+
+  returnStruct16BytesMixedResult = result;
+
+  return result;
+}
+
+/// Return value split over FP and integer register in x64.
+Struct16BytesMixed returnStruct16BytesMixed(double a0, int a1) {
+  print("returnStruct16BytesMixed(${a0}, ${a1})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct16BytesMixed throwing on purpuse!");
+  }
+
+  returnStruct16BytesMixed_a0 = a0;
+  returnStruct16BytesMixed_a1 = a1;
+
+  final result = returnStruct16BytesMixedCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct16BytesMixedAfterCallback() {
+  free(returnStruct16BytesMixedResult.addressOf);
+
+  final result = returnStruct16BytesMixedCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct16BytesMixedResult.addressOf);
+}
+
+typedef ReturnStruct16BytesMixed2Type = Struct16BytesMixed2 Function(
+    Float, Float, Float, Int32);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct16BytesMixed2_a0 = 0.0;
+double returnStruct16BytesMixed2_a1 = 0.0;
+double returnStruct16BytesMixed2_a2 = 0.0;
+int returnStruct16BytesMixed2_a3 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct16BytesMixed2 returnStruct16BytesMixed2Result = Struct16BytesMixed2();
+
+Struct16BytesMixed2 returnStruct16BytesMixed2CalculateResult() {
+  Struct16BytesMixed2 result = allocate<Struct16BytesMixed2>().ref;
+
+  result.a0 = returnStruct16BytesMixed2_a0;
+  result.a1 = returnStruct16BytesMixed2_a1;
+  result.a2 = returnStruct16BytesMixed2_a2;
+  result.a3 = returnStruct16BytesMixed2_a3;
+
+  returnStruct16BytesMixed2Result = result;
+
+  return result;
+}
+
+/// Return value split over FP and integer register in x64.
+/// The integer register contains half float half int.
+Struct16BytesMixed2 returnStruct16BytesMixed2(
+    double a0, double a1, double a2, int a3) {
+  print("returnStruct16BytesMixed2(${a0}, ${a1}, ${a2}, ${a3})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct16BytesMixed2 throwing on purpuse!");
+  }
+
+  returnStruct16BytesMixed2_a0 = a0;
+  returnStruct16BytesMixed2_a1 = a1;
+  returnStruct16BytesMixed2_a2 = a2;
+  returnStruct16BytesMixed2_a3 = a3;
+
+  final result = returnStruct16BytesMixed2CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct16BytesMixed2AfterCallback() {
+  free(returnStruct16BytesMixed2Result.addressOf);
+
+  final result = returnStruct16BytesMixed2CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct16BytesMixed2Result.addressOf);
+}
+
+typedef ReturnStruct17BytesIntType = Struct17BytesInt Function(
+    Int64, Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct17BytesInt_a0 = 0;
+int returnStruct17BytesInt_a1 = 0;
+int returnStruct17BytesInt_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct17BytesInt returnStruct17BytesIntResult = Struct17BytesInt();
+
+Struct17BytesInt returnStruct17BytesIntCalculateResult() {
+  Struct17BytesInt result = allocate<Struct17BytesInt>().ref;
+
+  result.a0 = returnStruct17BytesInt_a0;
+  result.a1 = returnStruct17BytesInt_a1;
+  result.a2 = returnStruct17BytesInt_a2;
+
+  returnStruct17BytesIntResult = result;
+
+  return result;
+}
+
+/// Rerturn value returned in preallocated space passed by pointer on most ABIs.
+/// Is non word size on purpose, to test that structs are rounded up to word size
+/// on all ABIs.
+Struct17BytesInt returnStruct17BytesInt(int a0, int a1, int a2) {
+  print("returnStruct17BytesInt(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct17BytesInt throwing on purpuse!");
+  }
+
+  returnStruct17BytesInt_a0 = a0;
+  returnStruct17BytesInt_a1 = a1;
+  returnStruct17BytesInt_a2 = a2;
+
+  final result = returnStruct17BytesIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct17BytesIntAfterCallback() {
+  free(returnStruct17BytesIntResult.addressOf);
+
+  final result = returnStruct17BytesIntCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct17BytesIntResult.addressOf);
+}
+
+typedef ReturnStruct19BytesHomogeneousUint8Type
+    = Struct19BytesHomogeneousUint8 Function(
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct19BytesHomogeneousUint8_a0 = 0;
+int returnStruct19BytesHomogeneousUint8_a1 = 0;
+int returnStruct19BytesHomogeneousUint8_a2 = 0;
+int returnStruct19BytesHomogeneousUint8_a3 = 0;
+int returnStruct19BytesHomogeneousUint8_a4 = 0;
+int returnStruct19BytesHomogeneousUint8_a5 = 0;
+int returnStruct19BytesHomogeneousUint8_a6 = 0;
+int returnStruct19BytesHomogeneousUint8_a7 = 0;
+int returnStruct19BytesHomogeneousUint8_a8 = 0;
+int returnStruct19BytesHomogeneousUint8_a9 = 0;
+int returnStruct19BytesHomogeneousUint8_a10 = 0;
+int returnStruct19BytesHomogeneousUint8_a11 = 0;
+int returnStruct19BytesHomogeneousUint8_a12 = 0;
+int returnStruct19BytesHomogeneousUint8_a13 = 0;
+int returnStruct19BytesHomogeneousUint8_a14 = 0;
+int returnStruct19BytesHomogeneousUint8_a15 = 0;
+int returnStruct19BytesHomogeneousUint8_a16 = 0;
+int returnStruct19BytesHomogeneousUint8_a17 = 0;
+int returnStruct19BytesHomogeneousUint8_a18 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct19BytesHomogeneousUint8 returnStruct19BytesHomogeneousUint8Result =
+    Struct19BytesHomogeneousUint8();
+
+Struct19BytesHomogeneousUint8
+    returnStruct19BytesHomogeneousUint8CalculateResult() {
+  Struct19BytesHomogeneousUint8 result =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+
+  result.a0 = returnStruct19BytesHomogeneousUint8_a0;
+  result.a1 = returnStruct19BytesHomogeneousUint8_a1;
+  result.a2 = returnStruct19BytesHomogeneousUint8_a2;
+  result.a3 = returnStruct19BytesHomogeneousUint8_a3;
+  result.a4 = returnStruct19BytesHomogeneousUint8_a4;
+  result.a5 = returnStruct19BytesHomogeneousUint8_a5;
+  result.a6 = returnStruct19BytesHomogeneousUint8_a6;
+  result.a7 = returnStruct19BytesHomogeneousUint8_a7;
+  result.a8 = returnStruct19BytesHomogeneousUint8_a8;
+  result.a9 = returnStruct19BytesHomogeneousUint8_a9;
+  result.a10 = returnStruct19BytesHomogeneousUint8_a10;
+  result.a11 = returnStruct19BytesHomogeneousUint8_a11;
+  result.a12 = returnStruct19BytesHomogeneousUint8_a12;
+  result.a13 = returnStruct19BytesHomogeneousUint8_a13;
+  result.a14 = returnStruct19BytesHomogeneousUint8_a14;
+  result.a15 = returnStruct19BytesHomogeneousUint8_a15;
+  result.a16 = returnStruct19BytesHomogeneousUint8_a16;
+  result.a17 = returnStruct19BytesHomogeneousUint8_a17;
+  result.a18 = returnStruct19BytesHomogeneousUint8_a18;
+
+  returnStruct19BytesHomogeneousUint8Result = result;
+
+  return result;
+}
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+Struct19BytesHomogeneousUint8 returnStruct19BytesHomogeneousUint8(
+    int a0,
+    int a1,
+    int a2,
+    int a3,
+    int a4,
+    int a5,
+    int a6,
+    int a7,
+    int a8,
+    int a9,
+    int a10,
+    int a11,
+    int a12,
+    int a13,
+    int a14,
+    int a15,
+    int a16,
+    int a17,
+    int a18) {
+  print(
+      "returnStruct19BytesHomogeneousUint8(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct19BytesHomogeneousUint8 throwing on purpuse!");
+  }
+
+  returnStruct19BytesHomogeneousUint8_a0 = a0;
+  returnStruct19BytesHomogeneousUint8_a1 = a1;
+  returnStruct19BytesHomogeneousUint8_a2 = a2;
+  returnStruct19BytesHomogeneousUint8_a3 = a3;
+  returnStruct19BytesHomogeneousUint8_a4 = a4;
+  returnStruct19BytesHomogeneousUint8_a5 = a5;
+  returnStruct19BytesHomogeneousUint8_a6 = a6;
+  returnStruct19BytesHomogeneousUint8_a7 = a7;
+  returnStruct19BytesHomogeneousUint8_a8 = a8;
+  returnStruct19BytesHomogeneousUint8_a9 = a9;
+  returnStruct19BytesHomogeneousUint8_a10 = a10;
+  returnStruct19BytesHomogeneousUint8_a11 = a11;
+  returnStruct19BytesHomogeneousUint8_a12 = a12;
+  returnStruct19BytesHomogeneousUint8_a13 = a13;
+  returnStruct19BytesHomogeneousUint8_a14 = a14;
+  returnStruct19BytesHomogeneousUint8_a15 = a15;
+  returnStruct19BytesHomogeneousUint8_a16 = a16;
+  returnStruct19BytesHomogeneousUint8_a17 = a17;
+  returnStruct19BytesHomogeneousUint8_a18 = a18;
+
+  final result = returnStruct19BytesHomogeneousUint8CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct19BytesHomogeneousUint8AfterCallback() {
+  free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+
+  final result = returnStruct19BytesHomogeneousUint8CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct19BytesHomogeneousUint8Result.addressOf);
+}
+
+typedef ReturnStruct20BytesHomogeneousInt32Type = Struct20BytesHomogeneousInt32
+    Function(Int32, Int32, Int32, Int32, Int32);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct20BytesHomogeneousInt32_a0 = 0;
+int returnStruct20BytesHomogeneousInt32_a1 = 0;
+int returnStruct20BytesHomogeneousInt32_a2 = 0;
+int returnStruct20BytesHomogeneousInt32_a3 = 0;
+int returnStruct20BytesHomogeneousInt32_a4 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousInt32 returnStruct20BytesHomogeneousInt32Result =
+    Struct20BytesHomogeneousInt32();
+
+Struct20BytesHomogeneousInt32
+    returnStruct20BytesHomogeneousInt32CalculateResult() {
+  Struct20BytesHomogeneousInt32 result =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  result.a0 = returnStruct20BytesHomogeneousInt32_a0;
+  result.a1 = returnStruct20BytesHomogeneousInt32_a1;
+  result.a2 = returnStruct20BytesHomogeneousInt32_a2;
+  result.a3 = returnStruct20BytesHomogeneousInt32_a3;
+  result.a4 = returnStruct20BytesHomogeneousInt32_a4;
+
+  returnStruct20BytesHomogeneousInt32Result = result;
+
+  return result;
+}
+
+/// Return value too big to go in cpu registers on arm64.
+Struct20BytesHomogeneousInt32 returnStruct20BytesHomogeneousInt32(
+    int a0, int a1, int a2, int a3, int a4) {
+  print(
+      "returnStruct20BytesHomogeneousInt32(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct20BytesHomogeneousInt32 throwing on purpuse!");
+  }
+
+  returnStruct20BytesHomogeneousInt32_a0 = a0;
+  returnStruct20BytesHomogeneousInt32_a1 = a1;
+  returnStruct20BytesHomogeneousInt32_a2 = a2;
+  returnStruct20BytesHomogeneousInt32_a3 = a3;
+  returnStruct20BytesHomogeneousInt32_a4 = a4;
+
+  final result = returnStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct20BytesHomogeneousInt32AfterCallback() {
+  free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+
+  final result = returnStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct20BytesHomogeneousInt32Result.addressOf);
+}
+
+typedef ReturnStruct20BytesHomogeneousFloatType = Struct20BytesHomogeneousFloat
+    Function(Float, Float, Float, Float, Float);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct20BytesHomogeneousFloat_a0 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a1 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a2 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a3 = 0.0;
+double returnStruct20BytesHomogeneousFloat_a4 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousFloat returnStruct20BytesHomogeneousFloatResult =
+    Struct20BytesHomogeneousFloat();
+
+Struct20BytesHomogeneousFloat
+    returnStruct20BytesHomogeneousFloatCalculateResult() {
+  Struct20BytesHomogeneousFloat result =
+      allocate<Struct20BytesHomogeneousFloat>().ref;
+
+  result.a0 = returnStruct20BytesHomogeneousFloat_a0;
+  result.a1 = returnStruct20BytesHomogeneousFloat_a1;
+  result.a2 = returnStruct20BytesHomogeneousFloat_a2;
+  result.a3 = returnStruct20BytesHomogeneousFloat_a3;
+  result.a4 = returnStruct20BytesHomogeneousFloat_a4;
+
+  returnStruct20BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
+Struct20BytesHomogeneousFloat returnStruct20BytesHomogeneousFloat(
+    double a0, double a1, double a2, double a3, double a4) {
+  print(
+      "returnStruct20BytesHomogeneousFloat(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStruct20BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStruct20BytesHomogeneousFloat_a0 = a0;
+  returnStruct20BytesHomogeneousFloat_a1 = a1;
+  returnStruct20BytesHomogeneousFloat_a2 = a2;
+  returnStruct20BytesHomogeneousFloat_a3 = a3;
+  returnStruct20BytesHomogeneousFloat_a4 = a4;
+
+  final result = returnStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct20BytesHomogeneousFloatAfterCallback() {
+  free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+
+  final result = returnStruct20BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct20BytesHomogeneousFloatResult.addressOf);
+}
+
+typedef ReturnStruct32BytesHomogeneousDoubleType
+    = Struct32BytesHomogeneousDouble Function(Double, Double, Double, Double);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct32BytesHomogeneousDouble_a0 = 0.0;
+double returnStruct32BytesHomogeneousDouble_a1 = 0.0;
+double returnStruct32BytesHomogeneousDouble_a2 = 0.0;
+double returnStruct32BytesHomogeneousDouble_a3 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct32BytesHomogeneousDouble returnStruct32BytesHomogeneousDoubleResult =
+    Struct32BytesHomogeneousDouble();
+
+Struct32BytesHomogeneousDouble
+    returnStruct32BytesHomogeneousDoubleCalculateResult() {
+  Struct32BytesHomogeneousDouble result =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+
+  result.a0 = returnStruct32BytesHomogeneousDouble_a0;
+  result.a1 = returnStruct32BytesHomogeneousDouble_a1;
+  result.a2 = returnStruct32BytesHomogeneousDouble_a2;
+  result.a3 = returnStruct32BytesHomogeneousDouble_a3;
+
+  returnStruct32BytesHomogeneousDoubleResult = result;
+
+  return result;
+}
+
+/// Return value in FPU registers on arm64.
+Struct32BytesHomogeneousDouble returnStruct32BytesHomogeneousDouble(
+    double a0, double a1, double a2, double a3) {
+  print("returnStruct32BytesHomogeneousDouble(${a0}, ${a1}, ${a2}, ${a3})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct32BytesHomogeneousDouble throwing on purpuse!");
+  }
+
+  returnStruct32BytesHomogeneousDouble_a0 = a0;
+  returnStruct32BytesHomogeneousDouble_a1 = a1;
+  returnStruct32BytesHomogeneousDouble_a2 = a2;
+  returnStruct32BytesHomogeneousDouble_a3 = a3;
+
+  final result = returnStruct32BytesHomogeneousDoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct32BytesHomogeneousDoubleAfterCallback() {
+  free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+
+  final result = returnStruct32BytesHomogeneousDoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct32BytesHomogeneousDoubleResult.addressOf);
+}
+
+typedef ReturnStruct40BytesHomogeneousDoubleType
+    = Struct40BytesHomogeneousDouble Function(
+        Double, Double, Double, Double, Double);
+
+// Global variables to be able to test inputs after callback returned.
+double returnStruct40BytesHomogeneousDouble_a0 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a1 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a2 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a3 = 0.0;
+double returnStruct40BytesHomogeneousDouble_a4 = 0.0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct40BytesHomogeneousDouble returnStruct40BytesHomogeneousDoubleResult =
+    Struct40BytesHomogeneousDouble();
+
+Struct40BytesHomogeneousDouble
+    returnStruct40BytesHomogeneousDoubleCalculateResult() {
+  Struct40BytesHomogeneousDouble result =
+      allocate<Struct40BytesHomogeneousDouble>().ref;
+
+  result.a0 = returnStruct40BytesHomogeneousDouble_a0;
+  result.a1 = returnStruct40BytesHomogeneousDouble_a1;
+  result.a2 = returnStruct40BytesHomogeneousDouble_a2;
+  result.a3 = returnStruct40BytesHomogeneousDouble_a3;
+  result.a4 = returnStruct40BytesHomogeneousDouble_a4;
+
+  returnStruct40BytesHomogeneousDoubleResult = result;
+
+  return result;
+}
+
+/// Return value too big to go in FPU registers on arm64.
+Struct40BytesHomogeneousDouble returnStruct40BytesHomogeneousDouble(
+    double a0, double a1, double a2, double a3, double a4) {
+  print(
+      "returnStruct40BytesHomogeneousDouble(${a0}, ${a1}, ${a2}, ${a3}, ${a4})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct40BytesHomogeneousDouble throwing on purpuse!");
+  }
+
+  returnStruct40BytesHomogeneousDouble_a0 = a0;
+  returnStruct40BytesHomogeneousDouble_a1 = a1;
+  returnStruct40BytesHomogeneousDouble_a2 = a2;
+  returnStruct40BytesHomogeneousDouble_a3 = a3;
+  returnStruct40BytesHomogeneousDouble_a4 = a4;
+
+  final result = returnStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct40BytesHomogeneousDoubleAfterCallback() {
+  free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+
+  final result = returnStruct40BytesHomogeneousDoubleCalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct40BytesHomogeneousDoubleResult.addressOf);
+}
+
+typedef ReturnStruct1024BytesHomogeneousUint64Type
+    = Struct1024BytesHomogeneousUint64 Function(
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStruct1024BytesHomogeneousUint64_a0 = 0;
+int returnStruct1024BytesHomogeneousUint64_a1 = 0;
+int returnStruct1024BytesHomogeneousUint64_a2 = 0;
+int returnStruct1024BytesHomogeneousUint64_a3 = 0;
+int returnStruct1024BytesHomogeneousUint64_a4 = 0;
+int returnStruct1024BytesHomogeneousUint64_a5 = 0;
+int returnStruct1024BytesHomogeneousUint64_a6 = 0;
+int returnStruct1024BytesHomogeneousUint64_a7 = 0;
+int returnStruct1024BytesHomogeneousUint64_a8 = 0;
+int returnStruct1024BytesHomogeneousUint64_a9 = 0;
+int returnStruct1024BytesHomogeneousUint64_a10 = 0;
+int returnStruct1024BytesHomogeneousUint64_a11 = 0;
+int returnStruct1024BytesHomogeneousUint64_a12 = 0;
+int returnStruct1024BytesHomogeneousUint64_a13 = 0;
+int returnStruct1024BytesHomogeneousUint64_a14 = 0;
+int returnStruct1024BytesHomogeneousUint64_a15 = 0;
+int returnStruct1024BytesHomogeneousUint64_a16 = 0;
+int returnStruct1024BytesHomogeneousUint64_a17 = 0;
+int returnStruct1024BytesHomogeneousUint64_a18 = 0;
+int returnStruct1024BytesHomogeneousUint64_a19 = 0;
+int returnStruct1024BytesHomogeneousUint64_a20 = 0;
+int returnStruct1024BytesHomogeneousUint64_a21 = 0;
+int returnStruct1024BytesHomogeneousUint64_a22 = 0;
+int returnStruct1024BytesHomogeneousUint64_a23 = 0;
+int returnStruct1024BytesHomogeneousUint64_a24 = 0;
+int returnStruct1024BytesHomogeneousUint64_a25 = 0;
+int returnStruct1024BytesHomogeneousUint64_a26 = 0;
+int returnStruct1024BytesHomogeneousUint64_a27 = 0;
+int returnStruct1024BytesHomogeneousUint64_a28 = 0;
+int returnStruct1024BytesHomogeneousUint64_a29 = 0;
+int returnStruct1024BytesHomogeneousUint64_a30 = 0;
+int returnStruct1024BytesHomogeneousUint64_a31 = 0;
+int returnStruct1024BytesHomogeneousUint64_a32 = 0;
+int returnStruct1024BytesHomogeneousUint64_a33 = 0;
+int returnStruct1024BytesHomogeneousUint64_a34 = 0;
+int returnStruct1024BytesHomogeneousUint64_a35 = 0;
+int returnStruct1024BytesHomogeneousUint64_a36 = 0;
+int returnStruct1024BytesHomogeneousUint64_a37 = 0;
+int returnStruct1024BytesHomogeneousUint64_a38 = 0;
+int returnStruct1024BytesHomogeneousUint64_a39 = 0;
+int returnStruct1024BytesHomogeneousUint64_a40 = 0;
+int returnStruct1024BytesHomogeneousUint64_a41 = 0;
+int returnStruct1024BytesHomogeneousUint64_a42 = 0;
+int returnStruct1024BytesHomogeneousUint64_a43 = 0;
+int returnStruct1024BytesHomogeneousUint64_a44 = 0;
+int returnStruct1024BytesHomogeneousUint64_a45 = 0;
+int returnStruct1024BytesHomogeneousUint64_a46 = 0;
+int returnStruct1024BytesHomogeneousUint64_a47 = 0;
+int returnStruct1024BytesHomogeneousUint64_a48 = 0;
+int returnStruct1024BytesHomogeneousUint64_a49 = 0;
+int returnStruct1024BytesHomogeneousUint64_a50 = 0;
+int returnStruct1024BytesHomogeneousUint64_a51 = 0;
+int returnStruct1024BytesHomogeneousUint64_a52 = 0;
+int returnStruct1024BytesHomogeneousUint64_a53 = 0;
+int returnStruct1024BytesHomogeneousUint64_a54 = 0;
+int returnStruct1024BytesHomogeneousUint64_a55 = 0;
+int returnStruct1024BytesHomogeneousUint64_a56 = 0;
+int returnStruct1024BytesHomogeneousUint64_a57 = 0;
+int returnStruct1024BytesHomogeneousUint64_a58 = 0;
+int returnStruct1024BytesHomogeneousUint64_a59 = 0;
+int returnStruct1024BytesHomogeneousUint64_a60 = 0;
+int returnStruct1024BytesHomogeneousUint64_a61 = 0;
+int returnStruct1024BytesHomogeneousUint64_a62 = 0;
+int returnStruct1024BytesHomogeneousUint64_a63 = 0;
+int returnStruct1024BytesHomogeneousUint64_a64 = 0;
+int returnStruct1024BytesHomogeneousUint64_a65 = 0;
+int returnStruct1024BytesHomogeneousUint64_a66 = 0;
+int returnStruct1024BytesHomogeneousUint64_a67 = 0;
+int returnStruct1024BytesHomogeneousUint64_a68 = 0;
+int returnStruct1024BytesHomogeneousUint64_a69 = 0;
+int returnStruct1024BytesHomogeneousUint64_a70 = 0;
+int returnStruct1024BytesHomogeneousUint64_a71 = 0;
+int returnStruct1024BytesHomogeneousUint64_a72 = 0;
+int returnStruct1024BytesHomogeneousUint64_a73 = 0;
+int returnStruct1024BytesHomogeneousUint64_a74 = 0;
+int returnStruct1024BytesHomogeneousUint64_a75 = 0;
+int returnStruct1024BytesHomogeneousUint64_a76 = 0;
+int returnStruct1024BytesHomogeneousUint64_a77 = 0;
+int returnStruct1024BytesHomogeneousUint64_a78 = 0;
+int returnStruct1024BytesHomogeneousUint64_a79 = 0;
+int returnStruct1024BytesHomogeneousUint64_a80 = 0;
+int returnStruct1024BytesHomogeneousUint64_a81 = 0;
+int returnStruct1024BytesHomogeneousUint64_a82 = 0;
+int returnStruct1024BytesHomogeneousUint64_a83 = 0;
+int returnStruct1024BytesHomogeneousUint64_a84 = 0;
+int returnStruct1024BytesHomogeneousUint64_a85 = 0;
+int returnStruct1024BytesHomogeneousUint64_a86 = 0;
+int returnStruct1024BytesHomogeneousUint64_a87 = 0;
+int returnStruct1024BytesHomogeneousUint64_a88 = 0;
+int returnStruct1024BytesHomogeneousUint64_a89 = 0;
+int returnStruct1024BytesHomogeneousUint64_a90 = 0;
+int returnStruct1024BytesHomogeneousUint64_a91 = 0;
+int returnStruct1024BytesHomogeneousUint64_a92 = 0;
+int returnStruct1024BytesHomogeneousUint64_a93 = 0;
+int returnStruct1024BytesHomogeneousUint64_a94 = 0;
+int returnStruct1024BytesHomogeneousUint64_a95 = 0;
+int returnStruct1024BytesHomogeneousUint64_a96 = 0;
+int returnStruct1024BytesHomogeneousUint64_a97 = 0;
+int returnStruct1024BytesHomogeneousUint64_a98 = 0;
+int returnStruct1024BytesHomogeneousUint64_a99 = 0;
+int returnStruct1024BytesHomogeneousUint64_a100 = 0;
+int returnStruct1024BytesHomogeneousUint64_a101 = 0;
+int returnStruct1024BytesHomogeneousUint64_a102 = 0;
+int returnStruct1024BytesHomogeneousUint64_a103 = 0;
+int returnStruct1024BytesHomogeneousUint64_a104 = 0;
+int returnStruct1024BytesHomogeneousUint64_a105 = 0;
+int returnStruct1024BytesHomogeneousUint64_a106 = 0;
+int returnStruct1024BytesHomogeneousUint64_a107 = 0;
+int returnStruct1024BytesHomogeneousUint64_a108 = 0;
+int returnStruct1024BytesHomogeneousUint64_a109 = 0;
+int returnStruct1024BytesHomogeneousUint64_a110 = 0;
+int returnStruct1024BytesHomogeneousUint64_a111 = 0;
+int returnStruct1024BytesHomogeneousUint64_a112 = 0;
+int returnStruct1024BytesHomogeneousUint64_a113 = 0;
+int returnStruct1024BytesHomogeneousUint64_a114 = 0;
+int returnStruct1024BytesHomogeneousUint64_a115 = 0;
+int returnStruct1024BytesHomogeneousUint64_a116 = 0;
+int returnStruct1024BytesHomogeneousUint64_a117 = 0;
+int returnStruct1024BytesHomogeneousUint64_a118 = 0;
+int returnStruct1024BytesHomogeneousUint64_a119 = 0;
+int returnStruct1024BytesHomogeneousUint64_a120 = 0;
+int returnStruct1024BytesHomogeneousUint64_a121 = 0;
+int returnStruct1024BytesHomogeneousUint64_a122 = 0;
+int returnStruct1024BytesHomogeneousUint64_a123 = 0;
+int returnStruct1024BytesHomogeneousUint64_a124 = 0;
+int returnStruct1024BytesHomogeneousUint64_a125 = 0;
+int returnStruct1024BytesHomogeneousUint64_a126 = 0;
+int returnStruct1024BytesHomogeneousUint64_a127 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+Struct1024BytesHomogeneousUint64 returnStruct1024BytesHomogeneousUint64Result =
+    Struct1024BytesHomogeneousUint64();
+
+Struct1024BytesHomogeneousUint64
+    returnStruct1024BytesHomogeneousUint64CalculateResult() {
+  Struct1024BytesHomogeneousUint64 result =
+      allocate<Struct1024BytesHomogeneousUint64>().ref;
+
+  result.a0 = returnStruct1024BytesHomogeneousUint64_a0;
+  result.a1 = returnStruct1024BytesHomogeneousUint64_a1;
+  result.a2 = returnStruct1024BytesHomogeneousUint64_a2;
+  result.a3 = returnStruct1024BytesHomogeneousUint64_a3;
+  result.a4 = returnStruct1024BytesHomogeneousUint64_a4;
+  result.a5 = returnStruct1024BytesHomogeneousUint64_a5;
+  result.a6 = returnStruct1024BytesHomogeneousUint64_a6;
+  result.a7 = returnStruct1024BytesHomogeneousUint64_a7;
+  result.a8 = returnStruct1024BytesHomogeneousUint64_a8;
+  result.a9 = returnStruct1024BytesHomogeneousUint64_a9;
+  result.a10 = returnStruct1024BytesHomogeneousUint64_a10;
+  result.a11 = returnStruct1024BytesHomogeneousUint64_a11;
+  result.a12 = returnStruct1024BytesHomogeneousUint64_a12;
+  result.a13 = returnStruct1024BytesHomogeneousUint64_a13;
+  result.a14 = returnStruct1024BytesHomogeneousUint64_a14;
+  result.a15 = returnStruct1024BytesHomogeneousUint64_a15;
+  result.a16 = returnStruct1024BytesHomogeneousUint64_a16;
+  result.a17 = returnStruct1024BytesHomogeneousUint64_a17;
+  result.a18 = returnStruct1024BytesHomogeneousUint64_a18;
+  result.a19 = returnStruct1024BytesHomogeneousUint64_a19;
+  result.a20 = returnStruct1024BytesHomogeneousUint64_a20;
+  result.a21 = returnStruct1024BytesHomogeneousUint64_a21;
+  result.a22 = returnStruct1024BytesHomogeneousUint64_a22;
+  result.a23 = returnStruct1024BytesHomogeneousUint64_a23;
+  result.a24 = returnStruct1024BytesHomogeneousUint64_a24;
+  result.a25 = returnStruct1024BytesHomogeneousUint64_a25;
+  result.a26 = returnStruct1024BytesHomogeneousUint64_a26;
+  result.a27 = returnStruct1024BytesHomogeneousUint64_a27;
+  result.a28 = returnStruct1024BytesHomogeneousUint64_a28;
+  result.a29 = returnStruct1024BytesHomogeneousUint64_a29;
+  result.a30 = returnStruct1024BytesHomogeneousUint64_a30;
+  result.a31 = returnStruct1024BytesHomogeneousUint64_a31;
+  result.a32 = returnStruct1024BytesHomogeneousUint64_a32;
+  result.a33 = returnStruct1024BytesHomogeneousUint64_a33;
+  result.a34 = returnStruct1024BytesHomogeneousUint64_a34;
+  result.a35 = returnStruct1024BytesHomogeneousUint64_a35;
+  result.a36 = returnStruct1024BytesHomogeneousUint64_a36;
+  result.a37 = returnStruct1024BytesHomogeneousUint64_a37;
+  result.a38 = returnStruct1024BytesHomogeneousUint64_a38;
+  result.a39 = returnStruct1024BytesHomogeneousUint64_a39;
+  result.a40 = returnStruct1024BytesHomogeneousUint64_a40;
+  result.a41 = returnStruct1024BytesHomogeneousUint64_a41;
+  result.a42 = returnStruct1024BytesHomogeneousUint64_a42;
+  result.a43 = returnStruct1024BytesHomogeneousUint64_a43;
+  result.a44 = returnStruct1024BytesHomogeneousUint64_a44;
+  result.a45 = returnStruct1024BytesHomogeneousUint64_a45;
+  result.a46 = returnStruct1024BytesHomogeneousUint64_a46;
+  result.a47 = returnStruct1024BytesHomogeneousUint64_a47;
+  result.a48 = returnStruct1024BytesHomogeneousUint64_a48;
+  result.a49 = returnStruct1024BytesHomogeneousUint64_a49;
+  result.a50 = returnStruct1024BytesHomogeneousUint64_a50;
+  result.a51 = returnStruct1024BytesHomogeneousUint64_a51;
+  result.a52 = returnStruct1024BytesHomogeneousUint64_a52;
+  result.a53 = returnStruct1024BytesHomogeneousUint64_a53;
+  result.a54 = returnStruct1024BytesHomogeneousUint64_a54;
+  result.a55 = returnStruct1024BytesHomogeneousUint64_a55;
+  result.a56 = returnStruct1024BytesHomogeneousUint64_a56;
+  result.a57 = returnStruct1024BytesHomogeneousUint64_a57;
+  result.a58 = returnStruct1024BytesHomogeneousUint64_a58;
+  result.a59 = returnStruct1024BytesHomogeneousUint64_a59;
+  result.a60 = returnStruct1024BytesHomogeneousUint64_a60;
+  result.a61 = returnStruct1024BytesHomogeneousUint64_a61;
+  result.a62 = returnStruct1024BytesHomogeneousUint64_a62;
+  result.a63 = returnStruct1024BytesHomogeneousUint64_a63;
+  result.a64 = returnStruct1024BytesHomogeneousUint64_a64;
+  result.a65 = returnStruct1024BytesHomogeneousUint64_a65;
+  result.a66 = returnStruct1024BytesHomogeneousUint64_a66;
+  result.a67 = returnStruct1024BytesHomogeneousUint64_a67;
+  result.a68 = returnStruct1024BytesHomogeneousUint64_a68;
+  result.a69 = returnStruct1024BytesHomogeneousUint64_a69;
+  result.a70 = returnStruct1024BytesHomogeneousUint64_a70;
+  result.a71 = returnStruct1024BytesHomogeneousUint64_a71;
+  result.a72 = returnStruct1024BytesHomogeneousUint64_a72;
+  result.a73 = returnStruct1024BytesHomogeneousUint64_a73;
+  result.a74 = returnStruct1024BytesHomogeneousUint64_a74;
+  result.a75 = returnStruct1024BytesHomogeneousUint64_a75;
+  result.a76 = returnStruct1024BytesHomogeneousUint64_a76;
+  result.a77 = returnStruct1024BytesHomogeneousUint64_a77;
+  result.a78 = returnStruct1024BytesHomogeneousUint64_a78;
+  result.a79 = returnStruct1024BytesHomogeneousUint64_a79;
+  result.a80 = returnStruct1024BytesHomogeneousUint64_a80;
+  result.a81 = returnStruct1024BytesHomogeneousUint64_a81;
+  result.a82 = returnStruct1024BytesHomogeneousUint64_a82;
+  result.a83 = returnStruct1024BytesHomogeneousUint64_a83;
+  result.a84 = returnStruct1024BytesHomogeneousUint64_a84;
+  result.a85 = returnStruct1024BytesHomogeneousUint64_a85;
+  result.a86 = returnStruct1024BytesHomogeneousUint64_a86;
+  result.a87 = returnStruct1024BytesHomogeneousUint64_a87;
+  result.a88 = returnStruct1024BytesHomogeneousUint64_a88;
+  result.a89 = returnStruct1024BytesHomogeneousUint64_a89;
+  result.a90 = returnStruct1024BytesHomogeneousUint64_a90;
+  result.a91 = returnStruct1024BytesHomogeneousUint64_a91;
+  result.a92 = returnStruct1024BytesHomogeneousUint64_a92;
+  result.a93 = returnStruct1024BytesHomogeneousUint64_a93;
+  result.a94 = returnStruct1024BytesHomogeneousUint64_a94;
+  result.a95 = returnStruct1024BytesHomogeneousUint64_a95;
+  result.a96 = returnStruct1024BytesHomogeneousUint64_a96;
+  result.a97 = returnStruct1024BytesHomogeneousUint64_a97;
+  result.a98 = returnStruct1024BytesHomogeneousUint64_a98;
+  result.a99 = returnStruct1024BytesHomogeneousUint64_a99;
+  result.a100 = returnStruct1024BytesHomogeneousUint64_a100;
+  result.a101 = returnStruct1024BytesHomogeneousUint64_a101;
+  result.a102 = returnStruct1024BytesHomogeneousUint64_a102;
+  result.a103 = returnStruct1024BytesHomogeneousUint64_a103;
+  result.a104 = returnStruct1024BytesHomogeneousUint64_a104;
+  result.a105 = returnStruct1024BytesHomogeneousUint64_a105;
+  result.a106 = returnStruct1024BytesHomogeneousUint64_a106;
+  result.a107 = returnStruct1024BytesHomogeneousUint64_a107;
+  result.a108 = returnStruct1024BytesHomogeneousUint64_a108;
+  result.a109 = returnStruct1024BytesHomogeneousUint64_a109;
+  result.a110 = returnStruct1024BytesHomogeneousUint64_a110;
+  result.a111 = returnStruct1024BytesHomogeneousUint64_a111;
+  result.a112 = returnStruct1024BytesHomogeneousUint64_a112;
+  result.a113 = returnStruct1024BytesHomogeneousUint64_a113;
+  result.a114 = returnStruct1024BytesHomogeneousUint64_a114;
+  result.a115 = returnStruct1024BytesHomogeneousUint64_a115;
+  result.a116 = returnStruct1024BytesHomogeneousUint64_a116;
+  result.a117 = returnStruct1024BytesHomogeneousUint64_a117;
+  result.a118 = returnStruct1024BytesHomogeneousUint64_a118;
+  result.a119 = returnStruct1024BytesHomogeneousUint64_a119;
+  result.a120 = returnStruct1024BytesHomogeneousUint64_a120;
+  result.a121 = returnStruct1024BytesHomogeneousUint64_a121;
+  result.a122 = returnStruct1024BytesHomogeneousUint64_a122;
+  result.a123 = returnStruct1024BytesHomogeneousUint64_a123;
+  result.a124 = returnStruct1024BytesHomogeneousUint64_a124;
+  result.a125 = returnStruct1024BytesHomogeneousUint64_a125;
+  result.a126 = returnStruct1024BytesHomogeneousUint64_a126;
+  result.a127 = returnStruct1024BytesHomogeneousUint64_a127;
+
+  returnStruct1024BytesHomogeneousUint64Result = result;
+
+  return result;
+}
+
+/// Test 1kb struct.
+Struct1024BytesHomogeneousUint64 returnStruct1024BytesHomogeneousUint64(
+    int a0,
+    int a1,
+    int a2,
+    int a3,
+    int a4,
+    int a5,
+    int a6,
+    int a7,
+    int a8,
+    int a9,
+    int a10,
+    int a11,
+    int a12,
+    int a13,
+    int a14,
+    int a15,
+    int a16,
+    int a17,
+    int a18,
+    int a19,
+    int a20,
+    int a21,
+    int a22,
+    int a23,
+    int a24,
+    int a25,
+    int a26,
+    int a27,
+    int a28,
+    int a29,
+    int a30,
+    int a31,
+    int a32,
+    int a33,
+    int a34,
+    int a35,
+    int a36,
+    int a37,
+    int a38,
+    int a39,
+    int a40,
+    int a41,
+    int a42,
+    int a43,
+    int a44,
+    int a45,
+    int a46,
+    int a47,
+    int a48,
+    int a49,
+    int a50,
+    int a51,
+    int a52,
+    int a53,
+    int a54,
+    int a55,
+    int a56,
+    int a57,
+    int a58,
+    int a59,
+    int a60,
+    int a61,
+    int a62,
+    int a63,
+    int a64,
+    int a65,
+    int a66,
+    int a67,
+    int a68,
+    int a69,
+    int a70,
+    int a71,
+    int a72,
+    int a73,
+    int a74,
+    int a75,
+    int a76,
+    int a77,
+    int a78,
+    int a79,
+    int a80,
+    int a81,
+    int a82,
+    int a83,
+    int a84,
+    int a85,
+    int a86,
+    int a87,
+    int a88,
+    int a89,
+    int a90,
+    int a91,
+    int a92,
+    int a93,
+    int a94,
+    int a95,
+    int a96,
+    int a97,
+    int a98,
+    int a99,
+    int a100,
+    int a101,
+    int a102,
+    int a103,
+    int a104,
+    int a105,
+    int a106,
+    int a107,
+    int a108,
+    int a109,
+    int a110,
+    int a111,
+    int a112,
+    int a113,
+    int a114,
+    int a115,
+    int a116,
+    int a117,
+    int a118,
+    int a119,
+    int a120,
+    int a121,
+    int a122,
+    int a123,
+    int a124,
+    int a125,
+    int a126,
+    int a127) {
+  print(
+      "returnStruct1024BytesHomogeneousUint64(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18}, ${a19}, ${a20}, ${a21}, ${a22}, ${a23}, ${a24}, ${a25}, ${a26}, ${a27}, ${a28}, ${a29}, ${a30}, ${a31}, ${a32}, ${a33}, ${a34}, ${a35}, ${a36}, ${a37}, ${a38}, ${a39}, ${a40}, ${a41}, ${a42}, ${a43}, ${a44}, ${a45}, ${a46}, ${a47}, ${a48}, ${a49}, ${a50}, ${a51}, ${a52}, ${a53}, ${a54}, ${a55}, ${a56}, ${a57}, ${a58}, ${a59}, ${a60}, ${a61}, ${a62}, ${a63}, ${a64}, ${a65}, ${a66}, ${a67}, ${a68}, ${a69}, ${a70}, ${a71}, ${a72}, ${a73}, ${a74}, ${a75}, ${a76}, ${a77}, ${a78}, ${a79}, ${a80}, ${a81}, ${a82}, ${a83}, ${a84}, ${a85}, ${a86}, ${a87}, ${a88}, ${a89}, ${a90}, ${a91}, ${a92}, ${a93}, ${a94}, ${a95}, ${a96}, ${a97}, ${a98}, ${a99}, ${a100}, ${a101}, ${a102}, ${a103}, ${a104}, ${a105}, ${a106}, ${a107}, ${a108}, ${a109}, ${a110}, ${a111}, ${a112}, ${a113}, ${a114}, ${a115}, ${a116}, ${a117}, ${a118}, ${a119}, ${a120}, ${a121}, ${a122}, ${a123}, ${a124}, ${a125}, ${a126}, ${a127})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStruct1024BytesHomogeneousUint64 throwing on purpuse!");
+  }
+
+  returnStruct1024BytesHomogeneousUint64_a0 = a0;
+  returnStruct1024BytesHomogeneousUint64_a1 = a1;
+  returnStruct1024BytesHomogeneousUint64_a2 = a2;
+  returnStruct1024BytesHomogeneousUint64_a3 = a3;
+  returnStruct1024BytesHomogeneousUint64_a4 = a4;
+  returnStruct1024BytesHomogeneousUint64_a5 = a5;
+  returnStruct1024BytesHomogeneousUint64_a6 = a6;
+  returnStruct1024BytesHomogeneousUint64_a7 = a7;
+  returnStruct1024BytesHomogeneousUint64_a8 = a8;
+  returnStruct1024BytesHomogeneousUint64_a9 = a9;
+  returnStruct1024BytesHomogeneousUint64_a10 = a10;
+  returnStruct1024BytesHomogeneousUint64_a11 = a11;
+  returnStruct1024BytesHomogeneousUint64_a12 = a12;
+  returnStruct1024BytesHomogeneousUint64_a13 = a13;
+  returnStruct1024BytesHomogeneousUint64_a14 = a14;
+  returnStruct1024BytesHomogeneousUint64_a15 = a15;
+  returnStruct1024BytesHomogeneousUint64_a16 = a16;
+  returnStruct1024BytesHomogeneousUint64_a17 = a17;
+  returnStruct1024BytesHomogeneousUint64_a18 = a18;
+  returnStruct1024BytesHomogeneousUint64_a19 = a19;
+  returnStruct1024BytesHomogeneousUint64_a20 = a20;
+  returnStruct1024BytesHomogeneousUint64_a21 = a21;
+  returnStruct1024BytesHomogeneousUint64_a22 = a22;
+  returnStruct1024BytesHomogeneousUint64_a23 = a23;
+  returnStruct1024BytesHomogeneousUint64_a24 = a24;
+  returnStruct1024BytesHomogeneousUint64_a25 = a25;
+  returnStruct1024BytesHomogeneousUint64_a26 = a26;
+  returnStruct1024BytesHomogeneousUint64_a27 = a27;
+  returnStruct1024BytesHomogeneousUint64_a28 = a28;
+  returnStruct1024BytesHomogeneousUint64_a29 = a29;
+  returnStruct1024BytesHomogeneousUint64_a30 = a30;
+  returnStruct1024BytesHomogeneousUint64_a31 = a31;
+  returnStruct1024BytesHomogeneousUint64_a32 = a32;
+  returnStruct1024BytesHomogeneousUint64_a33 = a33;
+  returnStruct1024BytesHomogeneousUint64_a34 = a34;
+  returnStruct1024BytesHomogeneousUint64_a35 = a35;
+  returnStruct1024BytesHomogeneousUint64_a36 = a36;
+  returnStruct1024BytesHomogeneousUint64_a37 = a37;
+  returnStruct1024BytesHomogeneousUint64_a38 = a38;
+  returnStruct1024BytesHomogeneousUint64_a39 = a39;
+  returnStruct1024BytesHomogeneousUint64_a40 = a40;
+  returnStruct1024BytesHomogeneousUint64_a41 = a41;
+  returnStruct1024BytesHomogeneousUint64_a42 = a42;
+  returnStruct1024BytesHomogeneousUint64_a43 = a43;
+  returnStruct1024BytesHomogeneousUint64_a44 = a44;
+  returnStruct1024BytesHomogeneousUint64_a45 = a45;
+  returnStruct1024BytesHomogeneousUint64_a46 = a46;
+  returnStruct1024BytesHomogeneousUint64_a47 = a47;
+  returnStruct1024BytesHomogeneousUint64_a48 = a48;
+  returnStruct1024BytesHomogeneousUint64_a49 = a49;
+  returnStruct1024BytesHomogeneousUint64_a50 = a50;
+  returnStruct1024BytesHomogeneousUint64_a51 = a51;
+  returnStruct1024BytesHomogeneousUint64_a52 = a52;
+  returnStruct1024BytesHomogeneousUint64_a53 = a53;
+  returnStruct1024BytesHomogeneousUint64_a54 = a54;
+  returnStruct1024BytesHomogeneousUint64_a55 = a55;
+  returnStruct1024BytesHomogeneousUint64_a56 = a56;
+  returnStruct1024BytesHomogeneousUint64_a57 = a57;
+  returnStruct1024BytesHomogeneousUint64_a58 = a58;
+  returnStruct1024BytesHomogeneousUint64_a59 = a59;
+  returnStruct1024BytesHomogeneousUint64_a60 = a60;
+  returnStruct1024BytesHomogeneousUint64_a61 = a61;
+  returnStruct1024BytesHomogeneousUint64_a62 = a62;
+  returnStruct1024BytesHomogeneousUint64_a63 = a63;
+  returnStruct1024BytesHomogeneousUint64_a64 = a64;
+  returnStruct1024BytesHomogeneousUint64_a65 = a65;
+  returnStruct1024BytesHomogeneousUint64_a66 = a66;
+  returnStruct1024BytesHomogeneousUint64_a67 = a67;
+  returnStruct1024BytesHomogeneousUint64_a68 = a68;
+  returnStruct1024BytesHomogeneousUint64_a69 = a69;
+  returnStruct1024BytesHomogeneousUint64_a70 = a70;
+  returnStruct1024BytesHomogeneousUint64_a71 = a71;
+  returnStruct1024BytesHomogeneousUint64_a72 = a72;
+  returnStruct1024BytesHomogeneousUint64_a73 = a73;
+  returnStruct1024BytesHomogeneousUint64_a74 = a74;
+  returnStruct1024BytesHomogeneousUint64_a75 = a75;
+  returnStruct1024BytesHomogeneousUint64_a76 = a76;
+  returnStruct1024BytesHomogeneousUint64_a77 = a77;
+  returnStruct1024BytesHomogeneousUint64_a78 = a78;
+  returnStruct1024BytesHomogeneousUint64_a79 = a79;
+  returnStruct1024BytesHomogeneousUint64_a80 = a80;
+  returnStruct1024BytesHomogeneousUint64_a81 = a81;
+  returnStruct1024BytesHomogeneousUint64_a82 = a82;
+  returnStruct1024BytesHomogeneousUint64_a83 = a83;
+  returnStruct1024BytesHomogeneousUint64_a84 = a84;
+  returnStruct1024BytesHomogeneousUint64_a85 = a85;
+  returnStruct1024BytesHomogeneousUint64_a86 = a86;
+  returnStruct1024BytesHomogeneousUint64_a87 = a87;
+  returnStruct1024BytesHomogeneousUint64_a88 = a88;
+  returnStruct1024BytesHomogeneousUint64_a89 = a89;
+  returnStruct1024BytesHomogeneousUint64_a90 = a90;
+  returnStruct1024BytesHomogeneousUint64_a91 = a91;
+  returnStruct1024BytesHomogeneousUint64_a92 = a92;
+  returnStruct1024BytesHomogeneousUint64_a93 = a93;
+  returnStruct1024BytesHomogeneousUint64_a94 = a94;
+  returnStruct1024BytesHomogeneousUint64_a95 = a95;
+  returnStruct1024BytesHomogeneousUint64_a96 = a96;
+  returnStruct1024BytesHomogeneousUint64_a97 = a97;
+  returnStruct1024BytesHomogeneousUint64_a98 = a98;
+  returnStruct1024BytesHomogeneousUint64_a99 = a99;
+  returnStruct1024BytesHomogeneousUint64_a100 = a100;
+  returnStruct1024BytesHomogeneousUint64_a101 = a101;
+  returnStruct1024BytesHomogeneousUint64_a102 = a102;
+  returnStruct1024BytesHomogeneousUint64_a103 = a103;
+  returnStruct1024BytesHomogeneousUint64_a104 = a104;
+  returnStruct1024BytesHomogeneousUint64_a105 = a105;
+  returnStruct1024BytesHomogeneousUint64_a106 = a106;
+  returnStruct1024BytesHomogeneousUint64_a107 = a107;
+  returnStruct1024BytesHomogeneousUint64_a108 = a108;
+  returnStruct1024BytesHomogeneousUint64_a109 = a109;
+  returnStruct1024BytesHomogeneousUint64_a110 = a110;
+  returnStruct1024BytesHomogeneousUint64_a111 = a111;
+  returnStruct1024BytesHomogeneousUint64_a112 = a112;
+  returnStruct1024BytesHomogeneousUint64_a113 = a113;
+  returnStruct1024BytesHomogeneousUint64_a114 = a114;
+  returnStruct1024BytesHomogeneousUint64_a115 = a115;
+  returnStruct1024BytesHomogeneousUint64_a116 = a116;
+  returnStruct1024BytesHomogeneousUint64_a117 = a117;
+  returnStruct1024BytesHomogeneousUint64_a118 = a118;
+  returnStruct1024BytesHomogeneousUint64_a119 = a119;
+  returnStruct1024BytesHomogeneousUint64_a120 = a120;
+  returnStruct1024BytesHomogeneousUint64_a121 = a121;
+  returnStruct1024BytesHomogeneousUint64_a122 = a122;
+  returnStruct1024BytesHomogeneousUint64_a123 = a123;
+  returnStruct1024BytesHomogeneousUint64_a124 = a124;
+  returnStruct1024BytesHomogeneousUint64_a125 = a125;
+  returnStruct1024BytesHomogeneousUint64_a126 = a126;
+  returnStruct1024BytesHomogeneousUint64_a127 = a127;
+
+  final result = returnStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStruct1024BytesHomogeneousUint64AfterCallback() {
+  free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+
+  final result = returnStruct1024BytesHomogeneousUint64CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStruct1024BytesHomogeneousUint64Result.addressOf);
+}
+
+typedef ReturnStructArgumentStruct1ByteIntType = Struct1ByteInt Function(
+    Struct1ByteInt);
+
+// Global variables to be able to test inputs after callback returned.
+Struct1ByteInt returnStructArgumentStruct1ByteInt_a0 = Struct1ByteInt();
+
+// Result variable also global, so we can delete it after the callback.
+Struct1ByteInt returnStructArgumentStruct1ByteIntResult = Struct1ByteInt();
+
+Struct1ByteInt returnStructArgumentStruct1ByteIntCalculateResult() {
+  Struct1ByteInt result = returnStructArgumentStruct1ByteInt_a0;
+
+  returnStructArgumentStruct1ByteIntResult = result;
+
+  return result;
+}
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in int registers in most ABIs.
+Struct1ByteInt returnStructArgumentStruct1ByteInt(Struct1ByteInt a0) {
+  print("returnStructArgumentStruct1ByteInt(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructArgumentStruct1ByteInt throwing on purpuse!");
+  }
+
+  returnStructArgumentStruct1ByteInt_a0 = a0;
+
+  final result = returnStructArgumentStruct1ByteIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentStruct1ByteIntAfterCallback() {
+  final result = returnStructArgumentStruct1ByteIntCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentInt32x8Struct1ByteIntType = Struct1ByteInt Function(
+    Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Struct1ByteInt);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructArgumentInt32x8Struct1ByteInt_a0 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a1 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a2 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a3 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a4 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a5 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a6 = 0;
+int returnStructArgumentInt32x8Struct1ByteInt_a7 = 0;
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteInt_a8 = Struct1ByteInt();
+
+// Result variable also global, so we can delete it after the callback.
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteIntResult =
+    Struct1ByteInt();
+
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteIntCalculateResult() {
+  Struct1ByteInt result = returnStructArgumentInt32x8Struct1ByteInt_a8;
+
+  returnStructArgumentInt32x8Struct1ByteIntResult = result;
+
+  return result;
+}
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed on stack on all ABIs.
+Struct1ByteInt returnStructArgumentInt32x8Struct1ByteInt(int a0, int a1, int a2,
+    int a3, int a4, int a5, int a6, int a7, Struct1ByteInt a8) {
+  print(
+      "returnStructArgumentInt32x8Struct1ByteInt(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentInt32x8Struct1ByteInt throwing on purpuse!");
+  }
+
+  returnStructArgumentInt32x8Struct1ByteInt_a0 = a0;
+  returnStructArgumentInt32x8Struct1ByteInt_a1 = a1;
+  returnStructArgumentInt32x8Struct1ByteInt_a2 = a2;
+  returnStructArgumentInt32x8Struct1ByteInt_a3 = a3;
+  returnStructArgumentInt32x8Struct1ByteInt_a4 = a4;
+  returnStructArgumentInt32x8Struct1ByteInt_a5 = a5;
+  returnStructArgumentInt32x8Struct1ByteInt_a6 = a6;
+  returnStructArgumentInt32x8Struct1ByteInt_a7 = a7;
+  returnStructArgumentInt32x8Struct1ByteInt_a8 = a8;
+
+  final result = returnStructArgumentInt32x8Struct1ByteIntCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentInt32x8Struct1ByteIntAfterCallback() {
+  final result = returnStructArgumentInt32x8Struct1ByteIntCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentStruct8BytesHomogeneousFloatType
+    = Struct8BytesHomogeneousFloat Function(Struct8BytesHomogeneousFloat);
+
+// Global variables to be able to test inputs after callback returned.
+Struct8BytesHomogeneousFloat
+    returnStructArgumentStruct8BytesHomogeneousFloat_a0 =
+    Struct8BytesHomogeneousFloat();
+
+// Result variable also global, so we can delete it after the callback.
+Struct8BytesHomogeneousFloat
+    returnStructArgumentStruct8BytesHomogeneousFloatResult =
+    Struct8BytesHomogeneousFloat();
+
+Struct8BytesHomogeneousFloat
+    returnStructArgumentStruct8BytesHomogeneousFloatCalculateResult() {
+  Struct8BytesHomogeneousFloat result =
+      returnStructArgumentStruct8BytesHomogeneousFloat_a0;
+
+  returnStructArgumentStruct8BytesHomogeneousFloatResult = result;
+
+  return result;
+}
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in float registers in most ABIs.
+Struct8BytesHomogeneousFloat returnStructArgumentStruct8BytesHomogeneousFloat(
+    Struct8BytesHomogeneousFloat a0) {
+  print("returnStructArgumentStruct8BytesHomogeneousFloat(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentStruct8BytesHomogeneousFloat throwing on purpuse!");
+  }
+
+  returnStructArgumentStruct8BytesHomogeneousFloat_a0 = a0;
+
+  final result =
+      returnStructArgumentStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentStruct8BytesHomogeneousFloatAfterCallback() {
+  final result =
+      returnStructArgumentStruct8BytesHomogeneousFloatCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentStruct20BytesHomogeneousInt32Type
+    = Struct20BytesHomogeneousInt32 Function(Struct20BytesHomogeneousInt32);
+
+// Global variables to be able to test inputs after callback returned.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentStruct20BytesHomogeneousInt32_a0 =
+    Struct20BytesHomogeneousInt32();
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentStruct20BytesHomogeneousInt32Result =
+    Struct20BytesHomogeneousInt32();
+
+Struct20BytesHomogeneousInt32
+    returnStructArgumentStruct20BytesHomogeneousInt32CalculateResult() {
+  Struct20BytesHomogeneousInt32 result =
+      returnStructArgumentStruct20BytesHomogeneousInt32_a0;
+
+  returnStructArgumentStruct20BytesHomogeneousInt32Result = result;
+
+  return result;
+}
+
+/// On arm64, both argument and return value are passed in by pointer.
+Struct20BytesHomogeneousInt32 returnStructArgumentStruct20BytesHomogeneousInt32(
+    Struct20BytesHomogeneousInt32 a0) {
+  print("returnStructArgumentStruct20BytesHomogeneousInt32(${a0})");
+
+  // In legacy mode, possibly return null.
+  if (a0.a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0.a0 == 42 || a0.a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentStruct20BytesHomogeneousInt32 throwing on purpuse!");
+  }
+
+  returnStructArgumentStruct20BytesHomogeneousInt32_a0 = a0;
+
+  final result =
+      returnStructArgumentStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentStruct20BytesHomogeneousInt32AfterCallback() {
+  final result =
+      returnStructArgumentStruct20BytesHomogeneousInt32CalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructArgumentInt32x8Struct20BytesHomogeneouType
+    = Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32, Int32,
+        Int32, Int32, Int32, Struct20BytesHomogeneousInt32);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a0 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a1 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a2 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a3 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a4 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a5 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a6 = 0;
+int returnStructArgumentInt32x8Struct20BytesHomogeneou_a7 = 0;
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneou_a8 =
+    Struct20BytesHomogeneousInt32();
+
+// Result variable also global, so we can delete it after the callback.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneouResult =
+    Struct20BytesHomogeneousInt32();
+
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneouCalculateResult() {
+  Struct20BytesHomogeneousInt32 result =
+      returnStructArgumentInt32x8Struct20BytesHomogeneou_a8;
+
+  returnStructArgumentInt32x8Struct20BytesHomogeneouResult = result;
+
+  return result;
+}
+
+/// On arm64, both argument and return value are passed in by pointer.
+/// Ints exhaust registers, so that pointer is passed on stack.
+Struct20BytesHomogeneousInt32
+    returnStructArgumentInt32x8Struct20BytesHomogeneou(
+        int a0,
+        int a1,
+        int a2,
+        int a3,
+        int a4,
+        int a5,
+        int a6,
+        int a7,
+        Struct20BytesHomogeneousInt32 a8) {
+  print(
+      "returnStructArgumentInt32x8Struct20BytesHomogeneou(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception(
+        "ReturnStructArgumentInt32x8Struct20BytesHomogeneou throwing on purpuse!");
+  }
+
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a0 = a0;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a1 = a1;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a2 = a2;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a3 = a3;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a4 = a4;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a5 = a5;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a6 = a6;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a7 = a7;
+  returnStructArgumentInt32x8Struct20BytesHomogeneou_a8 = a8;
+
+  final result =
+      returnStructArgumentInt32x8Struct20BytesHomogeneouCalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructArgumentInt32x8Struct20BytesHomogeneouAfterCallback() {
+  final result =
+      returnStructArgumentInt32x8Struct20BytesHomogeneouCalculateResult();
+
+  print("after callback result = $result");
+}
+
+typedef ReturnStructAlignmentInt16Type = StructAlignmentInt16 Function(
+    Int8, Int16, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructAlignmentInt16_a0 = 0;
+int returnStructAlignmentInt16_a1 = 0;
+int returnStructAlignmentInt16_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+StructAlignmentInt16 returnStructAlignmentInt16Result = StructAlignmentInt16();
+
+StructAlignmentInt16 returnStructAlignmentInt16CalculateResult() {
+  StructAlignmentInt16 result = allocate<StructAlignmentInt16>().ref;
+
+  result.a0 = returnStructAlignmentInt16_a0;
+  result.a1 = returnStructAlignmentInt16_a1;
+  result.a2 = returnStructAlignmentInt16_a2;
+
+  returnStructAlignmentInt16Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 16 byte int within struct.
+StructAlignmentInt16 returnStructAlignmentInt16(int a0, int a1, int a2) {
+  print("returnStructAlignmentInt16(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructAlignmentInt16 throwing on purpuse!");
+  }
+
+  returnStructAlignmentInt16_a0 = a0;
+  returnStructAlignmentInt16_a1 = a1;
+  returnStructAlignmentInt16_a2 = a2;
+
+  final result = returnStructAlignmentInt16CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructAlignmentInt16AfterCallback() {
+  free(returnStructAlignmentInt16Result.addressOf);
+
+  final result = returnStructAlignmentInt16CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStructAlignmentInt16Result.addressOf);
+}
+
+typedef ReturnStructAlignmentInt32Type = StructAlignmentInt32 Function(
+    Int8, Int32, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructAlignmentInt32_a0 = 0;
+int returnStructAlignmentInt32_a1 = 0;
+int returnStructAlignmentInt32_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+StructAlignmentInt32 returnStructAlignmentInt32Result = StructAlignmentInt32();
+
+StructAlignmentInt32 returnStructAlignmentInt32CalculateResult() {
+  StructAlignmentInt32 result = allocate<StructAlignmentInt32>().ref;
+
+  result.a0 = returnStructAlignmentInt32_a0;
+  result.a1 = returnStructAlignmentInt32_a1;
+  result.a2 = returnStructAlignmentInt32_a2;
+
+  returnStructAlignmentInt32Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 32 byte int within struct.
+StructAlignmentInt32 returnStructAlignmentInt32(int a0, int a1, int a2) {
+  print("returnStructAlignmentInt32(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructAlignmentInt32 throwing on purpuse!");
+  }
+
+  returnStructAlignmentInt32_a0 = a0;
+  returnStructAlignmentInt32_a1 = a1;
+  returnStructAlignmentInt32_a2 = a2;
+
+  final result = returnStructAlignmentInt32CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructAlignmentInt32AfterCallback() {
+  free(returnStructAlignmentInt32Result.addressOf);
+
+  final result = returnStructAlignmentInt32CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStructAlignmentInt32Result.addressOf);
+}
+
+typedef ReturnStructAlignmentInt64Type = StructAlignmentInt64 Function(
+    Int8, Int64, Int8);
+
+// Global variables to be able to test inputs after callback returned.
+int returnStructAlignmentInt64_a0 = 0;
+int returnStructAlignmentInt64_a1 = 0;
+int returnStructAlignmentInt64_a2 = 0;
+
+// Result variable also global, so we can delete it after the callback.
+StructAlignmentInt64 returnStructAlignmentInt64Result = StructAlignmentInt64();
+
+StructAlignmentInt64 returnStructAlignmentInt64CalculateResult() {
+  StructAlignmentInt64 result = allocate<StructAlignmentInt64>().ref;
+
+  result.a0 = returnStructAlignmentInt64_a0;
+  result.a1 = returnStructAlignmentInt64_a1;
+  result.a2 = returnStructAlignmentInt64_a2;
+
+  returnStructAlignmentInt64Result = result;
+
+  return result;
+}
+
+/// Test alignment and padding of 64 byte int within struct.
+StructAlignmentInt64 returnStructAlignmentInt64(int a0, int a1, int a2) {
+  print("returnStructAlignmentInt64(${a0}, ${a1}, ${a2})");
+
+  // In legacy mode, possibly return null.
+  if (a0 == 84) {
+    print("returning null!");
+    return null;
+  }
+
+  // In both nnbd and legacy mode, possibly throw.
+  if (a0 == 42 || a0 == 84) {
+    print("throwing!");
+    throw Exception("ReturnStructAlignmentInt64 throwing on purpuse!");
+  }
+
+  returnStructAlignmentInt64_a0 = a0;
+  returnStructAlignmentInt64_a1 = a1;
+  returnStructAlignmentInt64_a2 = a2;
+
+  final result = returnStructAlignmentInt64CalculateResult();
+
+  print("result = $result");
+
+  return result;
+}
+
+void returnStructAlignmentInt64AfterCallback() {
+  free(returnStructAlignmentInt64Result.addressOf);
+
+  final result = returnStructAlignmentInt64CalculateResult();
+
+  print("after callback result = $result");
+
+  free(returnStructAlignmentInt64Result.addressOf);
+}
diff --git a/tests/ffi_2/function_callbacks_structs_by_value_test.dart b/tests/ffi_2/function_callbacks_structs_by_value_test.dart
new file mode 100644
index 0000000..98ab518
--- /dev/null
+++ b/tests/ffi_2/function_callbacks_structs_by_value_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2020, 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
+//
+// VMOptions=--deterministic --optimization-counter-threshold=5 --use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+// Reuse the struct classes.
+import 'function_structs_by_value_generated_test.dart';
+
+void main() {
+  for (int i = 0; i < 10; i++) {
+    recursiveTest(10);
+    recursiveTest(11);
+  }
+}
+
+void recursiveTest(int recursionCounter) {
+  final struct = allocate<Struct20BytesHomogeneousInt32>().ref;
+  struct.a0 = 1;
+  struct.a1 = 2;
+  struct.a2 = 3;
+  struct.a3 = 4;
+  struct.a4 = 5;
+  final result = dartPassStructRecursive(recursionCounter, struct);
+  Expect.equals(struct.a0 + recursionCounter * 2, result.a0);
+  Expect.equals(struct.a1, result.a1);
+  Expect.equals(struct.a2, result.a2);
+  Expect.equals(struct.a3, result.a3);
+  Expect.equals(struct.a4, result.a4);
+  free(struct.addressOf);
+}
+
+Struct20BytesHomogeneousInt32 dartPassStructRecursive(
+    int recursionCounter, Struct20BytesHomogeneousInt32 struct) {
+  print("callbackPassStructRecurisive($recursionCounter, $struct)");
+  struct.a0++;
+  final structA0Saved = struct.a0;
+  if (recursionCounter <= 0) {
+    print("returning");
+    return struct;
+  }
+
+  final result =
+      cPassStructRecursive(recursionCounter - 1, struct, functionPointer);
+  result.a0++;
+
+  // Check struct.a0 is not modified by Dart->C call.
+  Expect.equals(structA0Saved, struct.a0);
+
+  // Check struct.a0 is not modified by C->Dart callback, if so struct.a4 == 0.
+  Expect.notEquals(0, struct.a4);
+
+  return result;
+}
+
+final functionPointer = Pointer.fromFunction<
+    Struct20BytesHomogeneousInt32 Function(
+        Int64, Struct20BytesHomogeneousInt32)>(dartPassStructRecursive);
+
+final cPassStructRecursive = ffiTestFunctions.lookupFunction<
+    Struct20BytesHomogeneousInt32 Function(Int64 recursionCounter,
+        Struct20BytesHomogeneousInt32 struct, Pointer callbackAddress),
+    Struct20BytesHomogeneousInt32 Function(int recursionCounter,
+        Struct20BytesHomogeneousInt32, Pointer)>("PassStructRecursive");
diff --git a/tests/ffi_2/function_structs_by_value_generated_test.dart b/tests/ffi_2/function_structs_by_value_generated_test.dart
new file mode 100644
index 0000000..d2c34dd
--- /dev/null
+++ b/tests/ffi_2/function_structs_by_value_generated_test.dart
@@ -0,0 +1,4720 @@
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=5
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'dylib_utils.dart';
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+void main() {
+  for (int i = 0; i < 10; ++i) {
+    testPassStruct1ByteIntx10();
+    testPassStruct3BytesIntx10();
+    testPassStruct4BytesHomogeneousInt16x10();
+    testPassStruct7BytesIntx10();
+    testPassStruct8BytesIntx10();
+    testPassStruct8BytesHomogeneousFloatx10();
+    testPassStruct8BytesMixedx10();
+    testPassStruct9BytesIntx10();
+    testPassStruct9BytesHomogeneousUint82x10();
+    testPassStruct12BytesHomogeneousFloatx6();
+    testPassStruct16BytesHomogeneousFloatx5();
+    testPassStruct16BytesMixedx10();
+    testPassStruct16BytesMixed2x10();
+    testPassStruct17BytesIntx10();
+    testPassStruct19BytesHomogeneousUint8x10();
+    testPassStruct20BytesHomogeneousInt32x10();
+    testPassStruct20BytesHomogeneousFloat();
+    testPassStruct32BytesHomogeneousDoublex5();
+    testPassStruct40BytesHomogeneousDouble();
+    testPassStruct1024BytesHomogeneousUint64();
+    testPassFloatStruct16BytesHomogeneousFloatFloatStruct1();
+    testPassFloatStruct32BytesHomogeneousDoubleFloatStruct();
+    testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn();
+    testPassDoublex6Struct16BytesMixedx4Int32();
+    testPassInt32x4Struct16BytesMixedx4Double();
+    testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo();
+    testPassStructAlignmentInt16();
+    testPassStructAlignmentInt32();
+    testPassStructAlignmentInt64();
+    testReturnStruct1ByteInt();
+    testReturnStruct3BytesInt();
+    testReturnStruct4BytesHomogeneousInt16();
+    testReturnStruct7BytesInt();
+    testReturnStruct8BytesInt();
+    testReturnStruct8BytesHomogeneousFloat();
+    testReturnStruct8BytesMixed();
+    testReturnStruct9BytesInt();
+    testReturnStruct9BytesHomogeneousUint82();
+    testReturnStruct12BytesHomogeneousFloat();
+    testReturnStruct16BytesHomogeneousFloat();
+    testReturnStruct16BytesMixed();
+    testReturnStruct16BytesMixed2();
+    testReturnStruct17BytesInt();
+    testReturnStruct19BytesHomogeneousUint8();
+    testReturnStruct20BytesHomogeneousInt32();
+    testReturnStruct20BytesHomogeneousFloat();
+    testReturnStruct32BytesHomogeneousDouble();
+    testReturnStruct40BytesHomogeneousDouble();
+    testReturnStruct1024BytesHomogeneousUint64();
+    testReturnStructArgumentStruct1ByteInt();
+    testReturnStructArgumentInt32x8Struct1ByteInt();
+    testReturnStructArgumentStruct8BytesHomogeneousFloat();
+    testReturnStructArgumentStruct20BytesHomogeneousInt32();
+    testReturnStructArgumentInt32x8Struct20BytesHomogeneou();
+    testReturnStructAlignmentInt16();
+    testReturnStructAlignmentInt32();
+    testReturnStructAlignmentInt64();
+  }
+}
+
+class Struct0Bytes extends Struct {
+  String toString() => "()";
+}
+
+class Struct1ByteInt extends Struct {
+  @Int8()
+  int a0;
+
+  String toString() => "(${a0})";
+}
+
+class Struct3BytesInt extends Struct {
+  @Int16()
+  int a0;
+
+  @Int8()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct4BytesHomogeneousInt16 extends Struct {
+  @Int16()
+  int a0;
+
+  @Int16()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct7BytesInt extends Struct {
+  @Int32()
+  int a0;
+
+  @Int16()
+  int a1;
+
+  @Int8()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct8BytesInt extends Struct {
+  @Int16()
+  int a0;
+
+  @Int16()
+  int a1;
+
+  @Int32()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct8BytesHomogeneousFloat extends Struct {
+  @Float()
+  double a0;
+
+  @Float()
+  double a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct8BytesMixed extends Struct {
+  @Float()
+  double a0;
+
+  @Int16()
+  int a1;
+
+  @Int16()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct9BytesInt extends Struct {
+  @Int64()
+  int a0;
+
+  @Int8()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct9BytesHomogeneousUint82 extends Struct {
+  @Uint8()
+  int a0;
+
+  @Uint8()
+  int a1;
+
+  @Uint8()
+  int a2;
+
+  @Uint8()
+  int a3;
+
+  @Uint8()
+  int a4;
+
+  @Uint8()
+  int a5;
+
+  @Uint8()
+  int a6;
+
+  @Uint8()
+  int a7;
+
+  @Uint8()
+  int a8;
+
+  String toString() =>
+      "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8})";
+}
+
+class Struct12BytesHomogeneousFloat extends Struct {
+  @Float()
+  double a0;
+
+  @Float()
+  double a1;
+
+  @Float()
+  double a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct16BytesHomogeneousFloat extends Struct {
+  @Float()
+  double a0;
+
+  @Float()
+  double a1;
+
+  @Float()
+  double a2;
+
+  @Float()
+  double a3;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3})";
+}
+
+class Struct16BytesMixed extends Struct {
+  @Double()
+  double a0;
+
+  @Int64()
+  int a1;
+
+  String toString() => "(${a0}, ${a1})";
+}
+
+class Struct16BytesMixed2 extends Struct {
+  @Float()
+  double a0;
+
+  @Float()
+  double a1;
+
+  @Float()
+  double a2;
+
+  @Int32()
+  int a3;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3})";
+}
+
+class Struct17BytesInt extends Struct {
+  @Int64()
+  int a0;
+
+  @Int64()
+  int a1;
+
+  @Int8()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class Struct19BytesHomogeneousUint8 extends Struct {
+  @Uint8()
+  int a0;
+
+  @Uint8()
+  int a1;
+
+  @Uint8()
+  int a2;
+
+  @Uint8()
+  int a3;
+
+  @Uint8()
+  int a4;
+
+  @Uint8()
+  int a5;
+
+  @Uint8()
+  int a6;
+
+  @Uint8()
+  int a7;
+
+  @Uint8()
+  int a8;
+
+  @Uint8()
+  int a9;
+
+  @Uint8()
+  int a10;
+
+  @Uint8()
+  int a11;
+
+  @Uint8()
+  int a12;
+
+  @Uint8()
+  int a13;
+
+  @Uint8()
+  int a14;
+
+  @Uint8()
+  int a15;
+
+  @Uint8()
+  int a16;
+
+  @Uint8()
+  int a17;
+
+  @Uint8()
+  int a18;
+
+  String toString() =>
+      "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18})";
+}
+
+class Struct20BytesHomogeneousInt32 extends Struct {
+  @Int32()
+  int a0;
+
+  @Int32()
+  int a1;
+
+  @Int32()
+  int a2;
+
+  @Int32()
+  int a3;
+
+  @Int32()
+  int a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+class Struct20BytesHomogeneousFloat extends Struct {
+  @Float()
+  double a0;
+
+  @Float()
+  double a1;
+
+  @Float()
+  double a2;
+
+  @Float()
+  double a3;
+
+  @Float()
+  double a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+class Struct32BytesHomogeneousDouble extends Struct {
+  @Double()
+  double a0;
+
+  @Double()
+  double a1;
+
+  @Double()
+  double a2;
+
+  @Double()
+  double a3;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3})";
+}
+
+class Struct40BytesHomogeneousDouble extends Struct {
+  @Double()
+  double a0;
+
+  @Double()
+  double a1;
+
+  @Double()
+  double a2;
+
+  @Double()
+  double a3;
+
+  @Double()
+  double a4;
+
+  String toString() => "(${a0}, ${a1}, ${a2}, ${a3}, ${a4})";
+}
+
+class Struct1024BytesHomogeneousUint64 extends Struct {
+  @Uint64()
+  int a0;
+
+  @Uint64()
+  int a1;
+
+  @Uint64()
+  int a2;
+
+  @Uint64()
+  int a3;
+
+  @Uint64()
+  int a4;
+
+  @Uint64()
+  int a5;
+
+  @Uint64()
+  int a6;
+
+  @Uint64()
+  int a7;
+
+  @Uint64()
+  int a8;
+
+  @Uint64()
+  int a9;
+
+  @Uint64()
+  int a10;
+
+  @Uint64()
+  int a11;
+
+  @Uint64()
+  int a12;
+
+  @Uint64()
+  int a13;
+
+  @Uint64()
+  int a14;
+
+  @Uint64()
+  int a15;
+
+  @Uint64()
+  int a16;
+
+  @Uint64()
+  int a17;
+
+  @Uint64()
+  int a18;
+
+  @Uint64()
+  int a19;
+
+  @Uint64()
+  int a20;
+
+  @Uint64()
+  int a21;
+
+  @Uint64()
+  int a22;
+
+  @Uint64()
+  int a23;
+
+  @Uint64()
+  int a24;
+
+  @Uint64()
+  int a25;
+
+  @Uint64()
+  int a26;
+
+  @Uint64()
+  int a27;
+
+  @Uint64()
+  int a28;
+
+  @Uint64()
+  int a29;
+
+  @Uint64()
+  int a30;
+
+  @Uint64()
+  int a31;
+
+  @Uint64()
+  int a32;
+
+  @Uint64()
+  int a33;
+
+  @Uint64()
+  int a34;
+
+  @Uint64()
+  int a35;
+
+  @Uint64()
+  int a36;
+
+  @Uint64()
+  int a37;
+
+  @Uint64()
+  int a38;
+
+  @Uint64()
+  int a39;
+
+  @Uint64()
+  int a40;
+
+  @Uint64()
+  int a41;
+
+  @Uint64()
+  int a42;
+
+  @Uint64()
+  int a43;
+
+  @Uint64()
+  int a44;
+
+  @Uint64()
+  int a45;
+
+  @Uint64()
+  int a46;
+
+  @Uint64()
+  int a47;
+
+  @Uint64()
+  int a48;
+
+  @Uint64()
+  int a49;
+
+  @Uint64()
+  int a50;
+
+  @Uint64()
+  int a51;
+
+  @Uint64()
+  int a52;
+
+  @Uint64()
+  int a53;
+
+  @Uint64()
+  int a54;
+
+  @Uint64()
+  int a55;
+
+  @Uint64()
+  int a56;
+
+  @Uint64()
+  int a57;
+
+  @Uint64()
+  int a58;
+
+  @Uint64()
+  int a59;
+
+  @Uint64()
+  int a60;
+
+  @Uint64()
+  int a61;
+
+  @Uint64()
+  int a62;
+
+  @Uint64()
+  int a63;
+
+  @Uint64()
+  int a64;
+
+  @Uint64()
+  int a65;
+
+  @Uint64()
+  int a66;
+
+  @Uint64()
+  int a67;
+
+  @Uint64()
+  int a68;
+
+  @Uint64()
+  int a69;
+
+  @Uint64()
+  int a70;
+
+  @Uint64()
+  int a71;
+
+  @Uint64()
+  int a72;
+
+  @Uint64()
+  int a73;
+
+  @Uint64()
+  int a74;
+
+  @Uint64()
+  int a75;
+
+  @Uint64()
+  int a76;
+
+  @Uint64()
+  int a77;
+
+  @Uint64()
+  int a78;
+
+  @Uint64()
+  int a79;
+
+  @Uint64()
+  int a80;
+
+  @Uint64()
+  int a81;
+
+  @Uint64()
+  int a82;
+
+  @Uint64()
+  int a83;
+
+  @Uint64()
+  int a84;
+
+  @Uint64()
+  int a85;
+
+  @Uint64()
+  int a86;
+
+  @Uint64()
+  int a87;
+
+  @Uint64()
+  int a88;
+
+  @Uint64()
+  int a89;
+
+  @Uint64()
+  int a90;
+
+  @Uint64()
+  int a91;
+
+  @Uint64()
+  int a92;
+
+  @Uint64()
+  int a93;
+
+  @Uint64()
+  int a94;
+
+  @Uint64()
+  int a95;
+
+  @Uint64()
+  int a96;
+
+  @Uint64()
+  int a97;
+
+  @Uint64()
+  int a98;
+
+  @Uint64()
+  int a99;
+
+  @Uint64()
+  int a100;
+
+  @Uint64()
+  int a101;
+
+  @Uint64()
+  int a102;
+
+  @Uint64()
+  int a103;
+
+  @Uint64()
+  int a104;
+
+  @Uint64()
+  int a105;
+
+  @Uint64()
+  int a106;
+
+  @Uint64()
+  int a107;
+
+  @Uint64()
+  int a108;
+
+  @Uint64()
+  int a109;
+
+  @Uint64()
+  int a110;
+
+  @Uint64()
+  int a111;
+
+  @Uint64()
+  int a112;
+
+  @Uint64()
+  int a113;
+
+  @Uint64()
+  int a114;
+
+  @Uint64()
+  int a115;
+
+  @Uint64()
+  int a116;
+
+  @Uint64()
+  int a117;
+
+  @Uint64()
+  int a118;
+
+  @Uint64()
+  int a119;
+
+  @Uint64()
+  int a120;
+
+  @Uint64()
+  int a121;
+
+  @Uint64()
+  int a122;
+
+  @Uint64()
+  int a123;
+
+  @Uint64()
+  int a124;
+
+  @Uint64()
+  int a125;
+
+  @Uint64()
+  int a126;
+
+  @Uint64()
+  int a127;
+
+  String toString() =>
+      "(${a0}, ${a1}, ${a2}, ${a3}, ${a4}, ${a5}, ${a6}, ${a7}, ${a8}, ${a9}, ${a10}, ${a11}, ${a12}, ${a13}, ${a14}, ${a15}, ${a16}, ${a17}, ${a18}, ${a19}, ${a20}, ${a21}, ${a22}, ${a23}, ${a24}, ${a25}, ${a26}, ${a27}, ${a28}, ${a29}, ${a30}, ${a31}, ${a32}, ${a33}, ${a34}, ${a35}, ${a36}, ${a37}, ${a38}, ${a39}, ${a40}, ${a41}, ${a42}, ${a43}, ${a44}, ${a45}, ${a46}, ${a47}, ${a48}, ${a49}, ${a50}, ${a51}, ${a52}, ${a53}, ${a54}, ${a55}, ${a56}, ${a57}, ${a58}, ${a59}, ${a60}, ${a61}, ${a62}, ${a63}, ${a64}, ${a65}, ${a66}, ${a67}, ${a68}, ${a69}, ${a70}, ${a71}, ${a72}, ${a73}, ${a74}, ${a75}, ${a76}, ${a77}, ${a78}, ${a79}, ${a80}, ${a81}, ${a82}, ${a83}, ${a84}, ${a85}, ${a86}, ${a87}, ${a88}, ${a89}, ${a90}, ${a91}, ${a92}, ${a93}, ${a94}, ${a95}, ${a96}, ${a97}, ${a98}, ${a99}, ${a100}, ${a101}, ${a102}, ${a103}, ${a104}, ${a105}, ${a106}, ${a107}, ${a108}, ${a109}, ${a110}, ${a111}, ${a112}, ${a113}, ${a114}, ${a115}, ${a116}, ${a117}, ${a118}, ${a119}, ${a120}, ${a121}, ${a122}, ${a123}, ${a124}, ${a125}, ${a126}, ${a127})";
+}
+
+class StructAlignmentInt16 extends Struct {
+  @Int8()
+  int a0;
+
+  @Int16()
+  int a1;
+
+  @Int8()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class StructAlignmentInt32 extends Struct {
+  @Int8()
+  int a0;
+
+  @Int32()
+  int a1;
+
+  @Int8()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+class StructAlignmentInt64 extends Struct {
+  @Int8()
+  int a0;
+
+  @Int64()
+  int a1;
+
+  @Int8()
+  int a2;
+
+  String toString() => "(${a0}, ${a1}, ${a2})";
+}
+
+final passStruct1ByteIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt),
+    int Function(
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt,
+        Struct1ByteInt)>("PassStruct1ByteIntx10");
+
+/// Smallest struct with data.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct1ByteIntx10() {
+  Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a1 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a2 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a3 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a4 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a5 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a6 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a7 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
+  Struct1ByteInt a9 = allocate<Struct1ByteInt>().ref;
+
+  a0.a0 = -1;
+  a1.a0 = 2;
+  a2.a0 = -3;
+  a3.a0 = 4;
+  a4.a0 = -5;
+  a5.a0 = 6;
+  a6.a0 = -7;
+  a7.a0 = 8;
+  a8.a0 = -9;
+  a9.a0 = 10;
+
+  final result = passStruct1ByteIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(5, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct3BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt),
+    int Function(
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt,
+        Struct3BytesInt)>("PassStruct3BytesIntx10");
+
+/// Not a multiple of word size, not a power of two.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct3BytesIntx10() {
+  Struct3BytesInt a0 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a1 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a2 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a3 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a4 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a5 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a6 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a7 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a8 = allocate<Struct3BytesInt>().ref;
+  Struct3BytesInt a9 = allocate<Struct3BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result = passStruct3BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct4BytesHomogeneousInt16x10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16),
+    int Function(
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16,
+        Struct4BytesHomogeneousInt16)>("PassStruct4BytesHomogeneousInt16x10");
+
+/// Exactly word size on 32-bit architectures.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct4BytesHomogeneousInt16x10() {
+  Struct4BytesHomogeneousInt16 a0 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a1 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a2 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a3 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a4 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a5 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a6 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a7 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a8 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct4BytesHomogeneousInt16 a9 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result = passStruct4BytesHomogeneousInt16x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct7BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt),
+    int Function(
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt,
+        Struct7BytesInt)>("PassStruct7BytesIntx10");
+
+/// Sub word size on 64 bit architectures.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct7BytesIntx10() {
+  Struct7BytesInt a0 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a1 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a2 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a3 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a4 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a5 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a6 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a7 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a8 = allocate<Struct7BytesInt>().ref;
+  Struct7BytesInt a9 = allocate<Struct7BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result = passStruct7BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(15, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct8BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt),
+    int Function(
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt,
+        Struct8BytesInt)>("PassStruct8BytesIntx10");
+
+/// Exactly word size struct on 64bit architectures.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct8BytesIntx10() {
+  Struct8BytesInt a0 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a1 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a2 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a3 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a4 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a5 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a6 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a7 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a8 = allocate<Struct8BytesInt>().ref;
+  Struct8BytesInt a9 = allocate<Struct8BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result = passStruct8BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(15, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct8BytesHomogeneousFloatx10 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat),
+    double Function(
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat,
+        Struct8BytesHomogeneousFloat)>("PassStruct8BytesHomogeneousFloatx10");
+
+/// Arguments passed in FP registers as long as they fit.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct8BytesHomogeneousFloatx10() {
+  Struct8BytesHomogeneousFloat a0 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a1 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a2 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a3 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a4 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a5 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a6 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a7 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a8 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+  Struct8BytesHomogeneousFloat a9 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a1.a0 = -3.0;
+  a1.a1 = 4.0;
+  a2.a0 = -5.0;
+  a2.a1 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a4.a0 = -9.0;
+  a4.a1 = 10.0;
+  a5.a0 = -11.0;
+  a5.a1 = 12.0;
+  a6.a0 = -13.0;
+  a6.a1 = 14.0;
+  a7.a0 = -15.0;
+  a7.a1 = 16.0;
+  a8.a0 = -17.0;
+  a8.a1 = 18.0;
+  a9.a0 = -19.0;
+  a9.a1 = 20.0;
+
+  final result = passStruct8BytesHomogeneousFloatx10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct8BytesMixedx10 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed),
+    double Function(
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed,
+        Struct8BytesMixed)>("PassStruct8BytesMixedx10");
+
+/// On x64, arguments go in int registers because it is not only float.
+/// 10 struct arguments will exhaust available registers.
+void testPassStruct8BytesMixedx10() {
+  Struct8BytesMixed a0 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a1 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a2 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a3 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a4 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a5 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a6 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a7 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a8 = allocate<Struct8BytesMixed>().ref;
+  Struct8BytesMixed a9 = allocate<Struct8BytesMixed>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4.0;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7.0;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10.0;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13.0;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16.0;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19.0;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22.0;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25.0;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28.0;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result =
+      passStruct8BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(15.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct9BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt),
+    int Function(
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt,
+        Struct9BytesInt)>("PassStruct9BytesIntx10");
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Tests upper bytes in the integer registers that are partly filled.
+/// Tests stack alignment of non word size stack arguments.
+void testPassStruct9BytesIntx10() {
+  Struct9BytesInt a0 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a1 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a2 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a3 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a4 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a5 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a6 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a7 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a8 = allocate<Struct9BytesInt>().ref;
+  Struct9BytesInt a9 = allocate<Struct9BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a1.a0 = -3;
+  a1.a1 = 4;
+  a2.a0 = -5;
+  a2.a1 = 6;
+  a3.a0 = -7;
+  a3.a1 = 8;
+  a4.a0 = -9;
+  a4.a1 = 10;
+  a5.a0 = -11;
+  a5.a1 = 12;
+  a6.a0 = -13;
+  a6.a1 = 14;
+  a7.a0 = -15;
+  a7.a1 = 16;
+  a8.a0 = -17;
+  a8.a1 = 18;
+  a9.a0 = -19;
+  a9.a1 = 20;
+
+  final result = passStruct9BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(10, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct9BytesHomogeneousUint82x10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82),
+    int Function(
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82,
+        Struct9BytesHomogeneousUint82)>("PassStruct9BytesHomogeneousUint82x10");
+
+/// Argument is a single byte over a multiple of word size.
+/// 10 struct arguments will exhaust available registers.
+/// Struct only has 1-byte aligned fields to test struct alignment itself.
+///
+void testPassStruct9BytesHomogeneousUint82x10() {
+  Struct9BytesHomogeneousUint82 a0 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a1 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a2 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a3 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a4 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a5 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a6 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a7 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a8 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+  Struct9BytesHomogeneousUint82 a9 =
+      allocate<Struct9BytesHomogeneousUint82>().ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a1.a0 = 10;
+  a1.a1 = 11;
+  a1.a2 = 12;
+  a1.a3 = 13;
+  a1.a4 = 14;
+  a1.a5 = 15;
+  a1.a6 = 16;
+  a1.a7 = 17;
+  a1.a8 = 18;
+  a2.a0 = 19;
+  a2.a1 = 20;
+  a2.a2 = 21;
+  a2.a3 = 22;
+  a2.a4 = 23;
+  a2.a5 = 24;
+  a2.a6 = 25;
+  a2.a7 = 26;
+  a2.a8 = 27;
+  a3.a0 = 28;
+  a3.a1 = 29;
+  a3.a2 = 30;
+  a3.a3 = 31;
+  a3.a4 = 32;
+  a3.a5 = 33;
+  a3.a6 = 34;
+  a3.a7 = 35;
+  a3.a8 = 36;
+  a4.a0 = 37;
+  a4.a1 = 38;
+  a4.a2 = 39;
+  a4.a3 = 40;
+  a4.a4 = 41;
+  a4.a5 = 42;
+  a4.a6 = 43;
+  a4.a7 = 44;
+  a4.a8 = 45;
+  a5.a0 = 46;
+  a5.a1 = 47;
+  a5.a2 = 48;
+  a5.a3 = 49;
+  a5.a4 = 50;
+  a5.a5 = 51;
+  a5.a6 = 52;
+  a5.a7 = 53;
+  a5.a8 = 54;
+  a6.a0 = 55;
+  a6.a1 = 56;
+  a6.a2 = 57;
+  a6.a3 = 58;
+  a6.a4 = 59;
+  a6.a5 = 60;
+  a6.a6 = 61;
+  a6.a7 = 62;
+  a6.a8 = 63;
+  a7.a0 = 64;
+  a7.a1 = 65;
+  a7.a2 = 66;
+  a7.a3 = 67;
+  a7.a4 = 68;
+  a7.a5 = 69;
+  a7.a6 = 70;
+  a7.a7 = 71;
+  a7.a8 = 72;
+  a8.a0 = 73;
+  a8.a1 = 74;
+  a8.a2 = 75;
+  a8.a3 = 76;
+  a8.a4 = 77;
+  a8.a5 = 78;
+  a8.a6 = 79;
+  a8.a7 = 80;
+  a8.a8 = 81;
+  a9.a0 = 82;
+  a9.a1 = 83;
+  a9.a2 = 84;
+  a9.a3 = 85;
+  a9.a4 = 86;
+  a9.a5 = 87;
+  a9.a6 = 88;
+  a9.a7 = 89;
+  a9.a8 = 90;
+
+  final result = passStruct9BytesHomogeneousUint82x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(4095, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct12BytesHomogeneousFloatx6 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat),
+    double Function(
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat,
+        Struct12BytesHomogeneousFloat)>("PassStruct12BytesHomogeneousFloatx6");
+
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// Struct arguments will exhaust available registers, and leave some empty.
+/// The last argument is to test whether arguments are backfilled.
+void testPassStruct12BytesHomogeneousFloatx6() {
+  Struct12BytesHomogeneousFloat a0 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a1 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a2 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a3 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a4 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+  Struct12BytesHomogeneousFloat a5 =
+      allocate<Struct12BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a1.a0 = 4.0;
+  a1.a1 = -5.0;
+  a1.a2 = 6.0;
+  a2.a0 = -7.0;
+  a2.a1 = 8.0;
+  a2.a2 = -9.0;
+  a3.a0 = 10.0;
+  a3.a1 = -11.0;
+  a3.a2 = 12.0;
+  a4.a0 = -13.0;
+  a4.a1 = 14.0;
+  a4.a2 = -15.0;
+  a5.a0 = 16.0;
+  a5.a1 = -17.0;
+  a5.a2 = 18.0;
+
+  final result = passStruct12BytesHomogeneousFloatx6(a0, a1, a2, a3, a4, a5);
+
+  print("result = $result");
+
+  Expect.approxEquals(9.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+}
+
+final passStruct16BytesHomogeneousFloatx5 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat),
+    double Function(
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat,
+        Struct16BytesHomogeneousFloat)>("PassStruct16BytesHomogeneousFloatx5");
+
+/// On Linux x64 argument is transferred on stack because it is over 16 bytes.
+/// Arguments in FPU registers on arm hardfp and arm64.
+/// 5 struct arguments will exhaust available registers.
+void testPassStruct16BytesHomogeneousFloatx5() {
+  Struct16BytesHomogeneousFloat a0 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a1 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a2 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a3 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  Struct16BytesHomogeneousFloat a4 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8.0;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12.0;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16.0;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20.0;
+
+  final result = passStruct16BytesHomogeneousFloatx5(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+}
+
+final passStruct16BytesMixedx10 = ffiTestFunctions.lookupFunction<
+    Double Function(
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed),
+    double Function(
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed)>("PassStruct16BytesMixedx10");
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 8 byte aligned.
+void testPassStruct16BytesMixedx10() {
+  Struct16BytesMixed a0 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a2 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2;
+  a1.a0 = -3.0;
+  a1.a1 = 4;
+  a2.a0 = -5.0;
+  a2.a1 = 6;
+  a3.a0 = -7.0;
+  a3.a1 = 8;
+  a4.a0 = -9.0;
+  a4.a1 = 10;
+  a5.a0 = -11.0;
+  a5.a1 = 12;
+  a6.a0 = -13.0;
+  a6.a1 = 14;
+  a7.a0 = -15.0;
+  a7.a1 = 16;
+  a8.a0 = -17.0;
+  a8.a1 = 18;
+  a9.a0 = -19.0;
+  a9.a1 = 20;
+
+  final result =
+      passStruct16BytesMixedx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct16BytesMixed2x10 = ffiTestFunctions.lookupFunction<
+    Float Function(
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2),
+    double Function(
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2,
+        Struct16BytesMixed2)>("PassStruct16BytesMixed2x10");
+
+/// On x64, arguments are split over FP and int registers.
+/// On x64, it will exhaust the integer registers with the 6th argument.
+/// The rest goes on the stack.
+/// On arm, arguments are 4 byte aligned.
+void testPassStruct16BytesMixed2x10() {
+  Struct16BytesMixed2 a0 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a1 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a2 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a3 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a4 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a5 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a6 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a7 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a8 = allocate<Struct16BytesMixed2>().ref;
+  Struct16BytesMixed2 a9 = allocate<Struct16BytesMixed2>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20;
+  a5.a0 = -21.0;
+  a5.a1 = 22.0;
+  a5.a2 = -23.0;
+  a5.a3 = 24;
+  a6.a0 = -25.0;
+  a6.a1 = 26.0;
+  a6.a2 = -27.0;
+  a6.a3 = 28;
+  a7.a0 = -29.0;
+  a7.a1 = 30.0;
+  a7.a2 = -31.0;
+  a7.a3 = 32;
+  a8.a0 = -33.0;
+  a8.a1 = 34.0;
+  a8.a2 = -35.0;
+  a8.a3 = 36;
+  a9.a0 = -37.0;
+  a9.a1 = 38.0;
+  a9.a2 = -39.0;
+  a9.a3 = 40;
+
+  final result =
+      passStruct16BytesMixed2x10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.approxEquals(20.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct17BytesIntx10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt),
+    int Function(
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt,
+        Struct17BytesInt)>("PassStruct17BytesIntx10");
+
+/// Arguments are passed as pointer to copy on arm64.
+/// Tests that the memory allocated for copies are rounded up to word size.
+void testPassStruct17BytesIntx10() {
+  Struct17BytesInt a0 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a1 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a2 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a3 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a4 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a5 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a6 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a7 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a8 = allocate<Struct17BytesInt>().ref;
+  Struct17BytesInt a9 = allocate<Struct17BytesInt>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a1.a0 = 4;
+  a1.a1 = -5;
+  a1.a2 = 6;
+  a2.a0 = -7;
+  a2.a1 = 8;
+  a2.a2 = -9;
+  a3.a0 = 10;
+  a3.a1 = -11;
+  a3.a2 = 12;
+  a4.a0 = -13;
+  a4.a1 = 14;
+  a4.a2 = -15;
+  a5.a0 = 16;
+  a5.a1 = -17;
+  a5.a2 = 18;
+  a6.a0 = -19;
+  a6.a1 = 20;
+  a6.a2 = -21;
+  a7.a0 = 22;
+  a7.a1 = -23;
+  a7.a2 = 24;
+  a8.a0 = -25;
+  a8.a1 = 26;
+  a8.a2 = -27;
+  a9.a0 = 28;
+  a9.a1 = -29;
+  a9.a2 = 30;
+
+  final result =
+      passStruct17BytesIntx10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(15, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct19BytesHomogeneousUint8x10 = ffiTestFunctions.lookupFunction<
+    Int64 Function(
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8),
+    int Function(
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8,
+        Struct19BytesHomogeneousUint8)>("PassStruct19BytesHomogeneousUint8x10");
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is extended to the right size.
+///
+void testPassStruct19BytesHomogeneousUint8x10() {
+  Struct19BytesHomogeneousUint8 a0 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a1 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a2 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a3 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a4 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a5 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a6 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a7 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a8 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+  Struct19BytesHomogeneousUint8 a9 =
+      allocate<Struct19BytesHomogeneousUint8>().ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a0.a9 = 10;
+  a0.a10 = 11;
+  a0.a11 = 12;
+  a0.a12 = 13;
+  a0.a13 = 14;
+  a0.a14 = 15;
+  a0.a15 = 16;
+  a0.a16 = 17;
+  a0.a17 = 18;
+  a0.a18 = 19;
+  a1.a0 = 20;
+  a1.a1 = 21;
+  a1.a2 = 22;
+  a1.a3 = 23;
+  a1.a4 = 24;
+  a1.a5 = 25;
+  a1.a6 = 26;
+  a1.a7 = 27;
+  a1.a8 = 28;
+  a1.a9 = 29;
+  a1.a10 = 30;
+  a1.a11 = 31;
+  a1.a12 = 32;
+  a1.a13 = 33;
+  a1.a14 = 34;
+  a1.a15 = 35;
+  a1.a16 = 36;
+  a1.a17 = 37;
+  a1.a18 = 38;
+  a2.a0 = 39;
+  a2.a1 = 40;
+  a2.a2 = 41;
+  a2.a3 = 42;
+  a2.a4 = 43;
+  a2.a5 = 44;
+  a2.a6 = 45;
+  a2.a7 = 46;
+  a2.a8 = 47;
+  a2.a9 = 48;
+  a2.a10 = 49;
+  a2.a11 = 50;
+  a2.a12 = 51;
+  a2.a13 = 52;
+  a2.a14 = 53;
+  a2.a15 = 54;
+  a2.a16 = 55;
+  a2.a17 = 56;
+  a2.a18 = 57;
+  a3.a0 = 58;
+  a3.a1 = 59;
+  a3.a2 = 60;
+  a3.a3 = 61;
+  a3.a4 = 62;
+  a3.a5 = 63;
+  a3.a6 = 64;
+  a3.a7 = 65;
+  a3.a8 = 66;
+  a3.a9 = 67;
+  a3.a10 = 68;
+  a3.a11 = 69;
+  a3.a12 = 70;
+  a3.a13 = 71;
+  a3.a14 = 72;
+  a3.a15 = 73;
+  a3.a16 = 74;
+  a3.a17 = 75;
+  a3.a18 = 76;
+  a4.a0 = 77;
+  a4.a1 = 78;
+  a4.a2 = 79;
+  a4.a3 = 80;
+  a4.a4 = 81;
+  a4.a5 = 82;
+  a4.a6 = 83;
+  a4.a7 = 84;
+  a4.a8 = 85;
+  a4.a9 = 86;
+  a4.a10 = 87;
+  a4.a11 = 88;
+  a4.a12 = 89;
+  a4.a13 = 90;
+  a4.a14 = 91;
+  a4.a15 = 92;
+  a4.a16 = 93;
+  a4.a17 = 94;
+  a4.a18 = 95;
+  a5.a0 = 96;
+  a5.a1 = 97;
+  a5.a2 = 98;
+  a5.a3 = 99;
+  a5.a4 = 100;
+  a5.a5 = 101;
+  a5.a6 = 102;
+  a5.a7 = 103;
+  a5.a8 = 104;
+  a5.a9 = 105;
+  a5.a10 = 106;
+  a5.a11 = 107;
+  a5.a12 = 108;
+  a5.a13 = 109;
+  a5.a14 = 110;
+  a5.a15 = 111;
+  a5.a16 = 112;
+  a5.a17 = 113;
+  a5.a18 = 114;
+  a6.a0 = 115;
+  a6.a1 = 116;
+  a6.a2 = 117;
+  a6.a3 = 118;
+  a6.a4 = 119;
+  a6.a5 = 120;
+  a6.a6 = 121;
+  a6.a7 = 122;
+  a6.a8 = 123;
+  a6.a9 = 124;
+  a6.a10 = 125;
+  a6.a11 = 126;
+  a6.a12 = 127;
+  a6.a13 = 128;
+  a6.a14 = 129;
+  a6.a15 = 130;
+  a6.a16 = 131;
+  a6.a17 = 132;
+  a6.a18 = 133;
+  a7.a0 = 134;
+  a7.a1 = 135;
+  a7.a2 = 136;
+  a7.a3 = 137;
+  a7.a4 = 138;
+  a7.a5 = 139;
+  a7.a6 = 140;
+  a7.a7 = 141;
+  a7.a8 = 142;
+  a7.a9 = 143;
+  a7.a10 = 144;
+  a7.a11 = 145;
+  a7.a12 = 146;
+  a7.a13 = 147;
+  a7.a14 = 148;
+  a7.a15 = 149;
+  a7.a16 = 150;
+  a7.a17 = 151;
+  a7.a18 = 152;
+  a8.a0 = 153;
+  a8.a1 = 154;
+  a8.a2 = 155;
+  a8.a3 = 156;
+  a8.a4 = 157;
+  a8.a5 = 158;
+  a8.a6 = 159;
+  a8.a7 = 160;
+  a8.a8 = 161;
+  a8.a9 = 162;
+  a8.a10 = 163;
+  a8.a11 = 164;
+  a8.a12 = 165;
+  a8.a13 = 166;
+  a8.a14 = 167;
+  a8.a15 = 168;
+  a8.a16 = 169;
+  a8.a17 = 170;
+  a8.a18 = 171;
+  a9.a0 = 172;
+  a9.a1 = 173;
+  a9.a2 = 174;
+  a9.a3 = 175;
+  a9.a4 = 176;
+  a9.a5 = 177;
+  a9.a6 = 178;
+  a9.a7 = 179;
+  a9.a8 = 180;
+  a9.a9 = 181;
+  a9.a10 = 182;
+  a9.a11 = 183;
+  a9.a12 = 184;
+  a9.a13 = 185;
+  a9.a14 = 186;
+  a9.a15 = 187;
+  a9.a16 = 188;
+  a9.a17 = 189;
+  a9.a18 = 190;
+
+  final result = passStruct19BytesHomogeneousUint8x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(18145, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct20BytesHomogeneousInt32x10 = ffiTestFunctions.lookupFunction<
+    Int32 Function(
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32),
+    int Function(
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32,
+        Struct20BytesHomogeneousInt32)>("PassStruct20BytesHomogeneousInt32x10");
+
+/// Argument too big to go into integer registers on arm64.
+/// The arguments are passed as pointers to copies.
+/// The amount of arguments exhausts the number of integer registers, such that
+/// pointers to copies are also passed on the stack.
+void testPassStruct20BytesHomogeneousInt32x10() {
+  Struct20BytesHomogeneousInt32 a0 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a1 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a2 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a3 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a4 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a5 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a6 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a7 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a8 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+  Struct20BytesHomogeneousInt32 a9 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a0.a3 = 4;
+  a0.a4 = -5;
+  a1.a0 = 6;
+  a1.a1 = -7;
+  a1.a2 = 8;
+  a1.a3 = -9;
+  a1.a4 = 10;
+  a2.a0 = -11;
+  a2.a1 = 12;
+  a2.a2 = -13;
+  a2.a3 = 14;
+  a2.a4 = -15;
+  a3.a0 = 16;
+  a3.a1 = -17;
+  a3.a2 = 18;
+  a3.a3 = -19;
+  a3.a4 = 20;
+  a4.a0 = -21;
+  a4.a1 = 22;
+  a4.a2 = -23;
+  a4.a3 = 24;
+  a4.a4 = -25;
+  a5.a0 = 26;
+  a5.a1 = -27;
+  a5.a2 = 28;
+  a5.a3 = -29;
+  a5.a4 = 30;
+  a6.a0 = -31;
+  a6.a1 = 32;
+  a6.a2 = -33;
+  a6.a3 = 34;
+  a6.a4 = -35;
+  a7.a0 = 36;
+  a7.a1 = -37;
+  a7.a2 = 38;
+  a7.a3 = -39;
+  a7.a4 = 40;
+  a8.a0 = -41;
+  a8.a1 = 42;
+  a8.a2 = -43;
+  a8.a3 = 44;
+  a8.a4 = -45;
+  a9.a0 = 46;
+  a9.a1 = -47;
+  a9.a2 = 48;
+  a9.a3 = -49;
+  a9.a4 = 50;
+
+  final result = passStruct20BytesHomogeneousInt32x10(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+
+  print("result = $result");
+
+  Expect.equals(25, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Float Function(Struct20BytesHomogeneousFloat),
+    double Function(
+        Struct20BytesHomogeneousFloat)>("PassStruct20BytesHomogeneousFloat");
+
+/// Argument too big to go into FPU registers in hardfp and arm64.
+void testPassStruct20BytesHomogeneousFloat() {
+  Struct20BytesHomogeneousFloat a0 =
+      allocate<Struct20BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+
+  final result = passStruct20BytesHomogeneousFloat(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(-3.0, result);
+
+  free(a0.addressOf);
+}
+
+final passStruct32BytesHomogeneousDoublex5 = ffiTestFunctions.lookupFunction<
+        Double Function(
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble),
+        double Function(
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble,
+            Struct32BytesHomogeneousDouble)>(
+    "PassStruct32BytesHomogeneousDoublex5");
+
+/// Arguments in FPU registers on arm64.
+/// 5 struct arguments will exhaust available registers.
+void testPassStruct32BytesHomogeneousDoublex5() {
+  Struct32BytesHomogeneousDouble a0 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a1 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a2 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a3 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  Struct32BytesHomogeneousDouble a4 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a1.a0 = -5.0;
+  a1.a1 = 6.0;
+  a1.a2 = -7.0;
+  a1.a3 = 8.0;
+  a2.a0 = -9.0;
+  a2.a1 = 10.0;
+  a2.a2 = -11.0;
+  a2.a3 = 12.0;
+  a3.a0 = -13.0;
+  a3.a1 = 14.0;
+  a3.a2 = -15.0;
+  a3.a3 = 16.0;
+  a4.a0 = -17.0;
+  a4.a1 = 18.0;
+  a4.a2 = -19.0;
+  a4.a3 = 20.0;
+
+  final result = passStruct32BytesHomogeneousDoublex5(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(10.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+  free(a3.addressOf);
+  free(a4.addressOf);
+}
+
+final passStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
+    Double Function(Struct40BytesHomogeneousDouble),
+    double Function(
+        Struct40BytesHomogeneousDouble)>("PassStruct40BytesHomogeneousDouble");
+
+/// Argument too big to go into FPU registers in arm64.
+void testPassStruct40BytesHomogeneousDouble() {
+  Struct40BytesHomogeneousDouble a0 =
+      allocate<Struct40BytesHomogeneousDouble>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+
+  final result = passStruct40BytesHomogeneousDouble(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(-3.0, result);
+
+  free(a0.addressOf);
+}
+
+final passStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
+        Uint64 Function(Struct1024BytesHomogeneousUint64),
+        int Function(Struct1024BytesHomogeneousUint64)>(
+    "PassStruct1024BytesHomogeneousUint64");
+
+/// Test 1kb struct.
+void testPassStruct1024BytesHomogeneousUint64() {
+  Struct1024BytesHomogeneousUint64 a0 =
+      allocate<Struct1024BytesHomogeneousUint64>().ref;
+
+  a0.a0 = 1;
+  a0.a1 = 2;
+  a0.a2 = 3;
+  a0.a3 = 4;
+  a0.a4 = 5;
+  a0.a5 = 6;
+  a0.a6 = 7;
+  a0.a7 = 8;
+  a0.a8 = 9;
+  a0.a9 = 10;
+  a0.a10 = 11;
+  a0.a11 = 12;
+  a0.a12 = 13;
+  a0.a13 = 14;
+  a0.a14 = 15;
+  a0.a15 = 16;
+  a0.a16 = 17;
+  a0.a17 = 18;
+  a0.a18 = 19;
+  a0.a19 = 20;
+  a0.a20 = 21;
+  a0.a21 = 22;
+  a0.a22 = 23;
+  a0.a23 = 24;
+  a0.a24 = 25;
+  a0.a25 = 26;
+  a0.a26 = 27;
+  a0.a27 = 28;
+  a0.a28 = 29;
+  a0.a29 = 30;
+  a0.a30 = 31;
+  a0.a31 = 32;
+  a0.a32 = 33;
+  a0.a33 = 34;
+  a0.a34 = 35;
+  a0.a35 = 36;
+  a0.a36 = 37;
+  a0.a37 = 38;
+  a0.a38 = 39;
+  a0.a39 = 40;
+  a0.a40 = 41;
+  a0.a41 = 42;
+  a0.a42 = 43;
+  a0.a43 = 44;
+  a0.a44 = 45;
+  a0.a45 = 46;
+  a0.a46 = 47;
+  a0.a47 = 48;
+  a0.a48 = 49;
+  a0.a49 = 50;
+  a0.a50 = 51;
+  a0.a51 = 52;
+  a0.a52 = 53;
+  a0.a53 = 54;
+  a0.a54 = 55;
+  a0.a55 = 56;
+  a0.a56 = 57;
+  a0.a57 = 58;
+  a0.a58 = 59;
+  a0.a59 = 60;
+  a0.a60 = 61;
+  a0.a61 = 62;
+  a0.a62 = 63;
+  a0.a63 = 64;
+  a0.a64 = 65;
+  a0.a65 = 66;
+  a0.a66 = 67;
+  a0.a67 = 68;
+  a0.a68 = 69;
+  a0.a69 = 70;
+  a0.a70 = 71;
+  a0.a71 = 72;
+  a0.a72 = 73;
+  a0.a73 = 74;
+  a0.a74 = 75;
+  a0.a75 = 76;
+  a0.a76 = 77;
+  a0.a77 = 78;
+  a0.a78 = 79;
+  a0.a79 = 80;
+  a0.a80 = 81;
+  a0.a81 = 82;
+  a0.a82 = 83;
+  a0.a83 = 84;
+  a0.a84 = 85;
+  a0.a85 = 86;
+  a0.a86 = 87;
+  a0.a87 = 88;
+  a0.a88 = 89;
+  a0.a89 = 90;
+  a0.a90 = 91;
+  a0.a91 = 92;
+  a0.a92 = 93;
+  a0.a93 = 94;
+  a0.a94 = 95;
+  a0.a95 = 96;
+  a0.a96 = 97;
+  a0.a97 = 98;
+  a0.a98 = 99;
+  a0.a99 = 100;
+  a0.a100 = 101;
+  a0.a101 = 102;
+  a0.a102 = 103;
+  a0.a103 = 104;
+  a0.a104 = 105;
+  a0.a105 = 106;
+  a0.a106 = 107;
+  a0.a107 = 108;
+  a0.a108 = 109;
+  a0.a109 = 110;
+  a0.a110 = 111;
+  a0.a111 = 112;
+  a0.a112 = 113;
+  a0.a113 = 114;
+  a0.a114 = 115;
+  a0.a115 = 116;
+  a0.a116 = 117;
+  a0.a117 = 118;
+  a0.a118 = 119;
+  a0.a119 = 120;
+  a0.a120 = 121;
+  a0.a121 = 122;
+  a0.a122 = 123;
+  a0.a123 = 124;
+  a0.a124 = 125;
+  a0.a125 = 126;
+  a0.a126 = 127;
+  a0.a127 = 128;
+
+  final result = passStruct1024BytesHomogeneousUint64(a0);
+
+  print("result = $result");
+
+  Expect.equals(8256, result);
+
+  free(a0.addressOf);
+}
+
+final passFloatStruct16BytesHomogeneousFloatFloatStruct1 =
+    ffiTestFunctions.lookupFunction<
+        Float Function(
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float,
+            Struct16BytesHomogeneousFloat,
+            Float),
+        double Function(
+            double,
+            Struct16BytesHomogeneousFloat,
+            double,
+            Struct16BytesHomogeneousFloat,
+            double,
+            Struct16BytesHomogeneousFloat,
+            double,
+            Struct16BytesHomogeneousFloat,
+            double)>("PassFloatStruct16BytesHomogeneousFloatFloatStruct1");
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+void testPassFloatStruct16BytesHomogeneousFloatFloatStruct1() {
+  double a0;
+  Struct16BytesHomogeneousFloat a1 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a2;
+  Struct16BytesHomogeneousFloat a3 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a4;
+  Struct16BytesHomogeneousFloat a5 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a6;
+  Struct16BytesHomogeneousFloat a7 =
+      allocate<Struct16BytesHomogeneousFloat>().ref;
+  double a8;
+
+  a0 = -1.0;
+  a1.a0 = 2.0;
+  a1.a1 = -3.0;
+  a1.a2 = 4.0;
+  a1.a3 = -5.0;
+  a2 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a3.a2 = -9.0;
+  a3.a3 = 10.0;
+  a4 = -11.0;
+  a5.a0 = 12.0;
+  a5.a1 = -13.0;
+  a5.a2 = 14.0;
+  a5.a3 = -15.0;
+  a6 = 16.0;
+  a7.a0 = -17.0;
+  a7.a1 = 18.0;
+  a7.a2 = -19.0;
+  a7.a3 = 20.0;
+  a8 = -21.0;
+
+  final result = passFloatStruct16BytesHomogeneousFloatFloatStruct1(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-11.0, result);
+
+  free(a1.addressOf);
+  free(a3.addressOf);
+  free(a5.addressOf);
+  free(a7.addressOf);
+}
+
+final passFloatStruct32BytesHomogeneousDoubleFloatStruct =
+    ffiTestFunctions.lookupFunction<
+        Double Function(
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float,
+            Struct32BytesHomogeneousDouble,
+            Float),
+        double Function(
+            double,
+            Struct32BytesHomogeneousDouble,
+            double,
+            Struct32BytesHomogeneousDouble,
+            double,
+            Struct32BytesHomogeneousDouble,
+            double,
+            Struct32BytesHomogeneousDouble,
+            double)>("PassFloatStruct32BytesHomogeneousDoubleFloatStruct");
+
+/// Tests the alignment of structs in FPU registers and backfilling.
+void testPassFloatStruct32BytesHomogeneousDoubleFloatStruct() {
+  double a0;
+  Struct32BytesHomogeneousDouble a1 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a2;
+  Struct32BytesHomogeneousDouble a3 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a4;
+  Struct32BytesHomogeneousDouble a5 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a6;
+  Struct32BytesHomogeneousDouble a7 =
+      allocate<Struct32BytesHomogeneousDouble>().ref;
+  double a8;
+
+  a0 = -1.0;
+  a1.a0 = 2.0;
+  a1.a1 = -3.0;
+  a1.a2 = 4.0;
+  a1.a3 = -5.0;
+  a2 = 6.0;
+  a3.a0 = -7.0;
+  a3.a1 = 8.0;
+  a3.a2 = -9.0;
+  a3.a3 = 10.0;
+  a4 = -11.0;
+  a5.a0 = 12.0;
+  a5.a1 = -13.0;
+  a5.a2 = 14.0;
+  a5.a3 = -15.0;
+  a6 = 16.0;
+  a7.a0 = -17.0;
+  a7.a1 = 18.0;
+  a7.a2 = -19.0;
+  a7.a3 = 20.0;
+  a8 = -21.0;
+
+  final result = passFloatStruct32BytesHomogeneousDoubleFloatStruct(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-11.0, result);
+
+  free(a1.addressOf);
+  free(a3.addressOf);
+  free(a5.addressOf);
+  free(a7.addressOf);
+}
+
+final passInt8Struct16BytesMixedInt8Struct16BytesMixedIn =
+    ffiTestFunctions.lookupFunction<
+        Double Function(Int8, Struct16BytesMixed, Int8, Struct16BytesMixed,
+            Int8, Struct16BytesMixed, Int8, Struct16BytesMixed, Int8),
+        double Function(
+            int,
+            Struct16BytesMixed,
+            int,
+            Struct16BytesMixed,
+            int,
+            Struct16BytesMixed,
+            int,
+            Struct16BytesMixed,
+            int)>("PassInt8Struct16BytesMixedInt8Struct16BytesMixedIn");
+
+/// Tests the alignment of structs in integers registers and on the stack.
+/// Arm32 aligns this struct at 8.
+/// Also, arm32 allocates the second struct partially in registers, partially
+/// on stack.
+/// Test backfilling of integer registers.
+void testPassInt8Struct16BytesMixedInt8Struct16BytesMixedIn() {
+  int a0;
+  Struct16BytesMixed a1 = allocate<Struct16BytesMixed>().ref;
+  int a2;
+  Struct16BytesMixed a3 = allocate<Struct16BytesMixed>().ref;
+  int a4;
+  Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+  int a6;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  int a8;
+
+  a0 = -1;
+  a1.a0 = 2.0;
+  a1.a1 = -3;
+  a2 = 4;
+  a3.a0 = -5.0;
+  a3.a1 = 6;
+  a4 = -7;
+  a5.a0 = 8.0;
+  a5.a1 = -9;
+  a6 = 10;
+  a7.a0 = -11.0;
+  a7.a1 = 12;
+  a8 = -13;
+
+  final result = passInt8Struct16BytesMixedInt8Struct16BytesMixedIn(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-7.0, result);
+
+  free(a1.addressOf);
+  free(a3.addressOf);
+  free(a5.addressOf);
+  free(a7.addressOf);
+}
+
+final passDoublex6Struct16BytesMixedx4Int32 = ffiTestFunctions.lookupFunction<
+    Double Function(
+        Double,
+        Double,
+        Double,
+        Double,
+        Double,
+        Double,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Int32),
+    double Function(
+        double,
+        double,
+        double,
+        double,
+        double,
+        double,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        int)>("PassDoublex6Struct16BytesMixedx4Int32");
+
+/// On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+/// structs. The rest of the structs will go on the stack.
+/// The int will be backfilled into the int register.
+void testPassDoublex6Struct16BytesMixedx4Int32() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+  double a5;
+  Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a8 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a9 = allocate<Struct16BytesMixed>().ref;
+  int a10;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+  a5 = 6.0;
+  a6.a0 = -7.0;
+  a6.a1 = 8;
+  a7.a0 = -9.0;
+  a7.a1 = 10;
+  a8.a0 = -11.0;
+  a8.a1 = 12;
+  a9.a0 = -13.0;
+  a9.a1 = 14;
+  a10 = -15;
+
+  final result = passDoublex6Struct16BytesMixedx4Int32(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+
+  print("result = $result");
+
+  Expect.approxEquals(-8.0, result);
+
+  free(a6.addressOf);
+  free(a7.addressOf);
+  free(a8.addressOf);
+  free(a9.addressOf);
+}
+
+final passInt32x4Struct16BytesMixedx4Double = ffiTestFunctions.lookupFunction<
+    Double Function(Int32, Int32, Int32, Int32, Struct16BytesMixed,
+        Struct16BytesMixed, Struct16BytesMixed, Struct16BytesMixed, Double),
+    double Function(
+        int,
+        int,
+        int,
+        int,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        Struct16BytesMixed,
+        double)>("PassInt32x4Struct16BytesMixedx4Double");
+
+/// On Linux x64, it will exhaust int registers first.
+/// The rest of the structs will go on the stack.
+/// The double will be backfilled into the xmm register.
+void testPassInt32x4Struct16BytesMixedx4Double() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  Struct16BytesMixed a4 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a5 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a6 = allocate<Struct16BytesMixed>().ref;
+  Struct16BytesMixed a7 = allocate<Struct16BytesMixed>().ref;
+  double a8;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4.a0 = -5.0;
+  a4.a1 = 6;
+  a5.a0 = -7.0;
+  a5.a1 = 8;
+  a6.a0 = -9.0;
+  a6.a1 = 10;
+  a7.a0 = -11.0;
+  a7.a1 = 12;
+  a8 = -13.0;
+
+  final result =
+      passInt32x4Struct16BytesMixedx4Double(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.approxEquals(-7.0, result);
+
+  free(a4.addressOf);
+  free(a5.addressOf);
+  free(a6.addressOf);
+  free(a7.addressOf);
+}
+
+final passStruct40BytesHomogeneousDoubleStruct4BytesHomo =
+    ffiTestFunctions.lookupFunction<
+            Double Function(Struct40BytesHomogeneousDouble,
+                Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat),
+            double Function(Struct40BytesHomogeneousDouble,
+                Struct4BytesHomogeneousInt16, Struct8BytesHomogeneousFloat)>(
+        "PassStruct40BytesHomogeneousDoubleStruct4BytesHomo");
+
+/// On various architectures, first struct is allocated on stack.
+/// Check that the other two arguments are allocated on registers.
+void testPassStruct40BytesHomogeneousDoubleStruct4BytesHomo() {
+  Struct40BytesHomogeneousDouble a0 =
+      allocate<Struct40BytesHomogeneousDouble>().ref;
+  Struct4BytesHomogeneousInt16 a1 =
+      allocate<Struct4BytesHomogeneousInt16>().ref;
+  Struct8BytesHomogeneousFloat a2 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+  a0.a2 = -3.0;
+  a0.a3 = 4.0;
+  a0.a4 = -5.0;
+  a1.a0 = 6;
+  a1.a1 = -7;
+  a2.a0 = 8.0;
+  a2.a1 = -9.0;
+
+  final result = passStruct40BytesHomogeneousDoubleStruct4BytesHomo(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.approxEquals(-5.0, result);
+
+  free(a0.addressOf);
+  free(a1.addressOf);
+  free(a2.addressOf);
+}
+
+final passStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
+    Int64 Function(StructAlignmentInt16),
+    int Function(StructAlignmentInt16)>("PassStructAlignmentInt16");
+
+/// Test alignment and padding of 16 byte int within struct.
+void testPassStructAlignmentInt16() {
+  StructAlignmentInt16 a0 = allocate<StructAlignmentInt16>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  final result = passStructAlignmentInt16(a0);
+
+  print("result = $result");
+
+  Expect.equals(-2, result);
+
+  free(a0.addressOf);
+}
+
+final passStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
+    Int64 Function(StructAlignmentInt32),
+    int Function(StructAlignmentInt32)>("PassStructAlignmentInt32");
+
+/// Test alignment and padding of 32 byte int within struct.
+void testPassStructAlignmentInt32() {
+  StructAlignmentInt32 a0 = allocate<StructAlignmentInt32>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  final result = passStructAlignmentInt32(a0);
+
+  print("result = $result");
+
+  Expect.equals(-2, result);
+
+  free(a0.addressOf);
+}
+
+final passStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
+    Int64 Function(StructAlignmentInt64),
+    int Function(StructAlignmentInt64)>("PassStructAlignmentInt64");
+
+/// Test alignment and padding of 64 byte int within struct.
+void testPassStructAlignmentInt64() {
+  StructAlignmentInt64 a0 = allocate<StructAlignmentInt64>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+
+  final result = passStructAlignmentInt64(a0);
+
+  print("result = $result");
+
+  Expect.equals(-2, result);
+
+  free(a0.addressOf);
+}
+
+final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
+    Struct1ByteInt Function(Int8),
+    Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
+
+/// Smallest struct with data.
+void testReturnStruct1ByteInt() {
+  int a0;
+
+  a0 = -1;
+
+  final result = returnStruct1ByteInt(a0);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+}
+
+final returnStruct3BytesInt = ffiTestFunctions.lookupFunction<
+    Struct3BytesInt Function(Int16, Int8),
+    Struct3BytesInt Function(int, int)>("ReturnStruct3BytesInt");
+
+/// Smaller than word size return value on all architectures.
+void testReturnStruct3BytesInt() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct3BytesInt(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct4BytesHomogeneousInt16 = ffiTestFunctions.lookupFunction<
+    Struct4BytesHomogeneousInt16 Function(Int16, Int16),
+    Struct4BytesHomogeneousInt16 Function(
+        int, int)>("ReturnStruct4BytesHomogeneousInt16");
+
+/// Word size return value on 32 bit architectures..
+void testReturnStruct4BytesHomogeneousInt16() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct4BytesHomogeneousInt16(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct7BytesInt = ffiTestFunctions.lookupFunction<
+    Struct7BytesInt Function(Int32, Int16, Int8),
+    Struct7BytesInt Function(int, int, int)>("ReturnStruct7BytesInt");
+
+/// Non-wordsize return value.
+void testReturnStruct7BytesInt() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct7BytesInt(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct8BytesInt = ffiTestFunctions.lookupFunction<
+    Struct8BytesInt Function(Int16, Int16, Int32),
+    Struct8BytesInt Function(int, int, int)>("ReturnStruct8BytesInt");
+
+/// Return value in integer registers on many architectures.
+void testReturnStruct8BytesInt() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct8BytesInt(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct8BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct8BytesHomogeneousFloat Function(Float, Float),
+    Struct8BytesHomogeneousFloat Function(
+        double, double)>("ReturnStruct8BytesHomogeneousFloat");
+
+/// Return value in FP registers on many architectures.
+void testReturnStruct8BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+
+  a0 = -1.0;
+  a1 = 2.0;
+
+  final result = returnStruct8BytesHomogeneousFloat(a0, a1);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+}
+
+final returnStruct8BytesMixed = ffiTestFunctions.lookupFunction<
+    Struct8BytesMixed Function(Float, Int16, Int16),
+    Struct8BytesMixed Function(double, int, int)>("ReturnStruct8BytesMixed");
+
+/// Return value split over FP and integer register in x64.
+void testReturnStruct8BytesMixed() {
+  double a0;
+  int a1;
+  int a2;
+
+  a0 = -1.0;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct8BytesMixed(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct9BytesInt = ffiTestFunctions.lookupFunction<
+    Struct9BytesInt Function(Int64, Int8),
+    Struct9BytesInt Function(int, int)>("ReturnStruct9BytesInt");
+
+/// Return value in two integer registers on x64.
+/// The second register only contains a single byte.
+void testReturnStruct9BytesInt() {
+  int a0;
+  int a1;
+
+  a0 = -1;
+  a1 = 2;
+
+  final result = returnStruct9BytesInt(a0, a1);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct9BytesHomogeneousUint82 = ffiTestFunctions.lookupFunction<
+    Struct9BytesHomogeneousUint82 Function(
+        Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8, Uint8),
+    Struct9BytesHomogeneousUint82 Function(int, int, int, int, int, int, int,
+        int, int)>("ReturnStruct9BytesHomogeneousUint82");
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+void testReturnStruct9BytesHomogeneousUint82() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  int a8;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+
+  final result =
+      returnStruct9BytesHomogeneousUint82(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+  Expect.equals(a7, result.a7);
+  Expect.equals(a8, result.a8);
+}
+
+final returnStruct12BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct12BytesHomogeneousFloat Function(Float, Float, Float),
+    Struct12BytesHomogeneousFloat Function(
+        double, double, double)>("ReturnStruct12BytesHomogeneousFloat");
+
+/// Return value in FPU registers, but does not use all registers on arm hardfp
+/// and arm64.
+void testReturnStruct12BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+  double a2;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+
+  final result = returnStruct12BytesHomogeneousFloat(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+}
+
+final returnStruct16BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct16BytesHomogeneousFloat Function(Float, Float, Float, Float),
+    Struct16BytesHomogeneousFloat Function(
+        double, double, double, double)>("ReturnStruct16BytesHomogeneousFloat");
+
+/// Return value in FPU registers on arm hardfp and arm64.
+void testReturnStruct16BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+
+  final result = returnStruct16BytesHomogeneousFloat(a0, a1, a2, a3);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+}
+
+final returnStruct16BytesMixed = ffiTestFunctions.lookupFunction<
+    Struct16BytesMixed Function(Double, Int64),
+    Struct16BytesMixed Function(double, int)>("ReturnStruct16BytesMixed");
+
+/// Return value split over FP and integer register in x64.
+void testReturnStruct16BytesMixed() {
+  double a0;
+  int a1;
+
+  a0 = -1.0;
+  a1 = 2;
+
+  final result = returnStruct16BytesMixed(a0, a1);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+}
+
+final returnStruct16BytesMixed2 = ffiTestFunctions.lookupFunction<
+    Struct16BytesMixed2 Function(Float, Float, Float, Int32),
+    Struct16BytesMixed2 Function(
+        double, double, double, int)>("ReturnStruct16BytesMixed2");
+
+/// Return value split over FP and integer register in x64.
+/// The integer register contains half float half int.
+void testReturnStruct16BytesMixed2() {
+  double a0;
+  double a1;
+  double a2;
+  int a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4;
+
+  final result = returnStruct16BytesMixed2(a0, a1, a2, a3);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+}
+
+final returnStruct17BytesInt = ffiTestFunctions.lookupFunction<
+    Struct17BytesInt Function(Int64, Int64, Int8),
+    Struct17BytesInt Function(int, int, int)>("ReturnStruct17BytesInt");
+
+/// Rerturn value returned in preallocated space passed by pointer on most ABIs.
+/// Is non word size on purpose, to test that structs are rounded up to word size
+/// on all ABIs.
+void testReturnStruct17BytesInt() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStruct17BytesInt(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStruct19BytesHomogeneousUint8 = ffiTestFunctions.lookupFunction<
+    Struct19BytesHomogeneousUint8 Function(
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8,
+        Uint8),
+    Struct19BytesHomogeneousUint8 Function(
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int)>("ReturnStruct19BytesHomogeneousUint8");
+
+/// The minimum alignment of this struct is only 1 byte based on its fields.
+/// Test that the memory backing these structs is the right size and that
+/// dart:ffi trampolines do not write outside this size.
+void testReturnStruct19BytesHomogeneousUint8() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  int a8;
+  int a9;
+  int a10;
+  int a11;
+  int a12;
+  int a13;
+  int a14;
+  int a15;
+  int a16;
+  int a17;
+  int a18;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+  a9 = 10;
+  a10 = 11;
+  a11 = 12;
+  a12 = 13;
+  a13 = 14;
+  a14 = 15;
+  a15 = 16;
+  a16 = 17;
+  a17 = 18;
+  a18 = 19;
+
+  final result = returnStruct19BytesHomogeneousUint8(a0, a1, a2, a3, a4, a5, a6,
+      a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+  Expect.equals(a7, result.a7);
+  Expect.equals(a8, result.a8);
+  Expect.equals(a9, result.a9);
+  Expect.equals(a10, result.a10);
+  Expect.equals(a11, result.a11);
+  Expect.equals(a12, result.a12);
+  Expect.equals(a13, result.a13);
+  Expect.equals(a14, result.a14);
+  Expect.equals(a15, result.a15);
+  Expect.equals(a16, result.a16);
+  Expect.equals(a17, result.a17);
+  Expect.equals(a18, result.a18);
+}
+
+final returnStruct20BytesHomogeneousInt32 = ffiTestFunctions.lookupFunction<
+    Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32, Int32),
+    Struct20BytesHomogeneousInt32 Function(
+        int, int, int, int, int)>("ReturnStruct20BytesHomogeneousInt32");
+
+/// Return value too big to go in cpu registers on arm64.
+void testReturnStruct20BytesHomogeneousInt32() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+
+  final result = returnStruct20BytesHomogeneousInt32(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+}
+
+final returnStruct20BytesHomogeneousFloat = ffiTestFunctions.lookupFunction<
+    Struct20BytesHomogeneousFloat Function(Float, Float, Float, Float, Float),
+    Struct20BytesHomogeneousFloat Function(double, double, double, double,
+        double)>("ReturnStruct20BytesHomogeneousFloat");
+
+/// Return value too big to go in FPU registers on x64, arm hardfp and arm64.
+void testReturnStruct20BytesHomogeneousFloat() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+
+  final result = returnStruct20BytesHomogeneousFloat(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+  Expect.approxEquals(a4, result.a4);
+}
+
+final returnStruct32BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
+    Struct32BytesHomogeneousDouble Function(Double, Double, Double, Double),
+    Struct32BytesHomogeneousDouble Function(double, double, double,
+        double)>("ReturnStruct32BytesHomogeneousDouble");
+
+/// Return value in FPU registers on arm64.
+void testReturnStruct32BytesHomogeneousDouble() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+
+  final result = returnStruct32BytesHomogeneousDouble(a0, a1, a2, a3);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+}
+
+final returnStruct40BytesHomogeneousDouble = ffiTestFunctions.lookupFunction<
+    Struct40BytesHomogeneousDouble Function(
+        Double, Double, Double, Double, Double),
+    Struct40BytesHomogeneousDouble Function(double, double, double, double,
+        double)>("ReturnStruct40BytesHomogeneousDouble");
+
+/// Return value too big to go in FPU registers on arm64.
+void testReturnStruct40BytesHomogeneousDouble() {
+  double a0;
+  double a1;
+  double a2;
+  double a3;
+  double a4;
+
+  a0 = -1.0;
+  a1 = 2.0;
+  a2 = -3.0;
+  a3 = 4.0;
+  a4 = -5.0;
+
+  final result = returnStruct40BytesHomogeneousDouble(a0, a1, a2, a3, a4);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0, result.a0);
+  Expect.approxEquals(a1, result.a1);
+  Expect.approxEquals(a2, result.a2);
+  Expect.approxEquals(a3, result.a3);
+  Expect.approxEquals(a4, result.a4);
+}
+
+final returnStruct1024BytesHomogeneousUint64 = ffiTestFunctions.lookupFunction<
+    Struct1024BytesHomogeneousUint64 Function(
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64,
+        Uint64),
+    Struct1024BytesHomogeneousUint64 Function(
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int,
+        int)>("ReturnStruct1024BytesHomogeneousUint64");
+
+/// Test 1kb struct.
+void testReturnStruct1024BytesHomogeneousUint64() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  int a8;
+  int a9;
+  int a10;
+  int a11;
+  int a12;
+  int a13;
+  int a14;
+  int a15;
+  int a16;
+  int a17;
+  int a18;
+  int a19;
+  int a20;
+  int a21;
+  int a22;
+  int a23;
+  int a24;
+  int a25;
+  int a26;
+  int a27;
+  int a28;
+  int a29;
+  int a30;
+  int a31;
+  int a32;
+  int a33;
+  int a34;
+  int a35;
+  int a36;
+  int a37;
+  int a38;
+  int a39;
+  int a40;
+  int a41;
+  int a42;
+  int a43;
+  int a44;
+  int a45;
+  int a46;
+  int a47;
+  int a48;
+  int a49;
+  int a50;
+  int a51;
+  int a52;
+  int a53;
+  int a54;
+  int a55;
+  int a56;
+  int a57;
+  int a58;
+  int a59;
+  int a60;
+  int a61;
+  int a62;
+  int a63;
+  int a64;
+  int a65;
+  int a66;
+  int a67;
+  int a68;
+  int a69;
+  int a70;
+  int a71;
+  int a72;
+  int a73;
+  int a74;
+  int a75;
+  int a76;
+  int a77;
+  int a78;
+  int a79;
+  int a80;
+  int a81;
+  int a82;
+  int a83;
+  int a84;
+  int a85;
+  int a86;
+  int a87;
+  int a88;
+  int a89;
+  int a90;
+  int a91;
+  int a92;
+  int a93;
+  int a94;
+  int a95;
+  int a96;
+  int a97;
+  int a98;
+  int a99;
+  int a100;
+  int a101;
+  int a102;
+  int a103;
+  int a104;
+  int a105;
+  int a106;
+  int a107;
+  int a108;
+  int a109;
+  int a110;
+  int a111;
+  int a112;
+  int a113;
+  int a114;
+  int a115;
+  int a116;
+  int a117;
+  int a118;
+  int a119;
+  int a120;
+  int a121;
+  int a122;
+  int a123;
+  int a124;
+  int a125;
+  int a126;
+  int a127;
+
+  a0 = 1;
+  a1 = 2;
+  a2 = 3;
+  a3 = 4;
+  a4 = 5;
+  a5 = 6;
+  a6 = 7;
+  a7 = 8;
+  a8 = 9;
+  a9 = 10;
+  a10 = 11;
+  a11 = 12;
+  a12 = 13;
+  a13 = 14;
+  a14 = 15;
+  a15 = 16;
+  a16 = 17;
+  a17 = 18;
+  a18 = 19;
+  a19 = 20;
+  a20 = 21;
+  a21 = 22;
+  a22 = 23;
+  a23 = 24;
+  a24 = 25;
+  a25 = 26;
+  a26 = 27;
+  a27 = 28;
+  a28 = 29;
+  a29 = 30;
+  a30 = 31;
+  a31 = 32;
+  a32 = 33;
+  a33 = 34;
+  a34 = 35;
+  a35 = 36;
+  a36 = 37;
+  a37 = 38;
+  a38 = 39;
+  a39 = 40;
+  a40 = 41;
+  a41 = 42;
+  a42 = 43;
+  a43 = 44;
+  a44 = 45;
+  a45 = 46;
+  a46 = 47;
+  a47 = 48;
+  a48 = 49;
+  a49 = 50;
+  a50 = 51;
+  a51 = 52;
+  a52 = 53;
+  a53 = 54;
+  a54 = 55;
+  a55 = 56;
+  a56 = 57;
+  a57 = 58;
+  a58 = 59;
+  a59 = 60;
+  a60 = 61;
+  a61 = 62;
+  a62 = 63;
+  a63 = 64;
+  a64 = 65;
+  a65 = 66;
+  a66 = 67;
+  a67 = 68;
+  a68 = 69;
+  a69 = 70;
+  a70 = 71;
+  a71 = 72;
+  a72 = 73;
+  a73 = 74;
+  a74 = 75;
+  a75 = 76;
+  a76 = 77;
+  a77 = 78;
+  a78 = 79;
+  a79 = 80;
+  a80 = 81;
+  a81 = 82;
+  a82 = 83;
+  a83 = 84;
+  a84 = 85;
+  a85 = 86;
+  a86 = 87;
+  a87 = 88;
+  a88 = 89;
+  a89 = 90;
+  a90 = 91;
+  a91 = 92;
+  a92 = 93;
+  a93 = 94;
+  a94 = 95;
+  a95 = 96;
+  a96 = 97;
+  a97 = 98;
+  a98 = 99;
+  a99 = 100;
+  a100 = 101;
+  a101 = 102;
+  a102 = 103;
+  a103 = 104;
+  a104 = 105;
+  a105 = 106;
+  a106 = 107;
+  a107 = 108;
+  a108 = 109;
+  a109 = 110;
+  a110 = 111;
+  a111 = 112;
+  a112 = 113;
+  a113 = 114;
+  a114 = 115;
+  a115 = 116;
+  a116 = 117;
+  a117 = 118;
+  a118 = 119;
+  a119 = 120;
+  a120 = 121;
+  a121 = 122;
+  a122 = 123;
+  a123 = 124;
+  a124 = 125;
+  a125 = 126;
+  a126 = 127;
+  a127 = 128;
+
+  final result = returnStruct1024BytesHomogeneousUint64(
+      a0,
+      a1,
+      a2,
+      a3,
+      a4,
+      a5,
+      a6,
+      a7,
+      a8,
+      a9,
+      a10,
+      a11,
+      a12,
+      a13,
+      a14,
+      a15,
+      a16,
+      a17,
+      a18,
+      a19,
+      a20,
+      a21,
+      a22,
+      a23,
+      a24,
+      a25,
+      a26,
+      a27,
+      a28,
+      a29,
+      a30,
+      a31,
+      a32,
+      a33,
+      a34,
+      a35,
+      a36,
+      a37,
+      a38,
+      a39,
+      a40,
+      a41,
+      a42,
+      a43,
+      a44,
+      a45,
+      a46,
+      a47,
+      a48,
+      a49,
+      a50,
+      a51,
+      a52,
+      a53,
+      a54,
+      a55,
+      a56,
+      a57,
+      a58,
+      a59,
+      a60,
+      a61,
+      a62,
+      a63,
+      a64,
+      a65,
+      a66,
+      a67,
+      a68,
+      a69,
+      a70,
+      a71,
+      a72,
+      a73,
+      a74,
+      a75,
+      a76,
+      a77,
+      a78,
+      a79,
+      a80,
+      a81,
+      a82,
+      a83,
+      a84,
+      a85,
+      a86,
+      a87,
+      a88,
+      a89,
+      a90,
+      a91,
+      a92,
+      a93,
+      a94,
+      a95,
+      a96,
+      a97,
+      a98,
+      a99,
+      a100,
+      a101,
+      a102,
+      a103,
+      a104,
+      a105,
+      a106,
+      a107,
+      a108,
+      a109,
+      a110,
+      a111,
+      a112,
+      a113,
+      a114,
+      a115,
+      a116,
+      a117,
+      a118,
+      a119,
+      a120,
+      a121,
+      a122,
+      a123,
+      a124,
+      a125,
+      a126,
+      a127);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+  Expect.equals(a3, result.a3);
+  Expect.equals(a4, result.a4);
+  Expect.equals(a5, result.a5);
+  Expect.equals(a6, result.a6);
+  Expect.equals(a7, result.a7);
+  Expect.equals(a8, result.a8);
+  Expect.equals(a9, result.a9);
+  Expect.equals(a10, result.a10);
+  Expect.equals(a11, result.a11);
+  Expect.equals(a12, result.a12);
+  Expect.equals(a13, result.a13);
+  Expect.equals(a14, result.a14);
+  Expect.equals(a15, result.a15);
+  Expect.equals(a16, result.a16);
+  Expect.equals(a17, result.a17);
+  Expect.equals(a18, result.a18);
+  Expect.equals(a19, result.a19);
+  Expect.equals(a20, result.a20);
+  Expect.equals(a21, result.a21);
+  Expect.equals(a22, result.a22);
+  Expect.equals(a23, result.a23);
+  Expect.equals(a24, result.a24);
+  Expect.equals(a25, result.a25);
+  Expect.equals(a26, result.a26);
+  Expect.equals(a27, result.a27);
+  Expect.equals(a28, result.a28);
+  Expect.equals(a29, result.a29);
+  Expect.equals(a30, result.a30);
+  Expect.equals(a31, result.a31);
+  Expect.equals(a32, result.a32);
+  Expect.equals(a33, result.a33);
+  Expect.equals(a34, result.a34);
+  Expect.equals(a35, result.a35);
+  Expect.equals(a36, result.a36);
+  Expect.equals(a37, result.a37);
+  Expect.equals(a38, result.a38);
+  Expect.equals(a39, result.a39);
+  Expect.equals(a40, result.a40);
+  Expect.equals(a41, result.a41);
+  Expect.equals(a42, result.a42);
+  Expect.equals(a43, result.a43);
+  Expect.equals(a44, result.a44);
+  Expect.equals(a45, result.a45);
+  Expect.equals(a46, result.a46);
+  Expect.equals(a47, result.a47);
+  Expect.equals(a48, result.a48);
+  Expect.equals(a49, result.a49);
+  Expect.equals(a50, result.a50);
+  Expect.equals(a51, result.a51);
+  Expect.equals(a52, result.a52);
+  Expect.equals(a53, result.a53);
+  Expect.equals(a54, result.a54);
+  Expect.equals(a55, result.a55);
+  Expect.equals(a56, result.a56);
+  Expect.equals(a57, result.a57);
+  Expect.equals(a58, result.a58);
+  Expect.equals(a59, result.a59);
+  Expect.equals(a60, result.a60);
+  Expect.equals(a61, result.a61);
+  Expect.equals(a62, result.a62);
+  Expect.equals(a63, result.a63);
+  Expect.equals(a64, result.a64);
+  Expect.equals(a65, result.a65);
+  Expect.equals(a66, result.a66);
+  Expect.equals(a67, result.a67);
+  Expect.equals(a68, result.a68);
+  Expect.equals(a69, result.a69);
+  Expect.equals(a70, result.a70);
+  Expect.equals(a71, result.a71);
+  Expect.equals(a72, result.a72);
+  Expect.equals(a73, result.a73);
+  Expect.equals(a74, result.a74);
+  Expect.equals(a75, result.a75);
+  Expect.equals(a76, result.a76);
+  Expect.equals(a77, result.a77);
+  Expect.equals(a78, result.a78);
+  Expect.equals(a79, result.a79);
+  Expect.equals(a80, result.a80);
+  Expect.equals(a81, result.a81);
+  Expect.equals(a82, result.a82);
+  Expect.equals(a83, result.a83);
+  Expect.equals(a84, result.a84);
+  Expect.equals(a85, result.a85);
+  Expect.equals(a86, result.a86);
+  Expect.equals(a87, result.a87);
+  Expect.equals(a88, result.a88);
+  Expect.equals(a89, result.a89);
+  Expect.equals(a90, result.a90);
+  Expect.equals(a91, result.a91);
+  Expect.equals(a92, result.a92);
+  Expect.equals(a93, result.a93);
+  Expect.equals(a94, result.a94);
+  Expect.equals(a95, result.a95);
+  Expect.equals(a96, result.a96);
+  Expect.equals(a97, result.a97);
+  Expect.equals(a98, result.a98);
+  Expect.equals(a99, result.a99);
+  Expect.equals(a100, result.a100);
+  Expect.equals(a101, result.a101);
+  Expect.equals(a102, result.a102);
+  Expect.equals(a103, result.a103);
+  Expect.equals(a104, result.a104);
+  Expect.equals(a105, result.a105);
+  Expect.equals(a106, result.a106);
+  Expect.equals(a107, result.a107);
+  Expect.equals(a108, result.a108);
+  Expect.equals(a109, result.a109);
+  Expect.equals(a110, result.a110);
+  Expect.equals(a111, result.a111);
+  Expect.equals(a112, result.a112);
+  Expect.equals(a113, result.a113);
+  Expect.equals(a114, result.a114);
+  Expect.equals(a115, result.a115);
+  Expect.equals(a116, result.a116);
+  Expect.equals(a117, result.a117);
+  Expect.equals(a118, result.a118);
+  Expect.equals(a119, result.a119);
+  Expect.equals(a120, result.a120);
+  Expect.equals(a121, result.a121);
+  Expect.equals(a122, result.a122);
+  Expect.equals(a123, result.a123);
+  Expect.equals(a124, result.a124);
+  Expect.equals(a125, result.a125);
+  Expect.equals(a126, result.a126);
+  Expect.equals(a127, result.a127);
+}
+
+final returnStructArgumentStruct1ByteInt = ffiTestFunctions.lookupFunction<
+    Struct1ByteInt Function(Struct1ByteInt),
+    Struct1ByteInt Function(
+        Struct1ByteInt)>("ReturnStructArgumentStruct1ByteInt");
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in int registers in most ABIs.
+void testReturnStructArgumentStruct1ByteInt() {
+  Struct1ByteInt a0 = allocate<Struct1ByteInt>().ref;
+
+  a0.a0 = -1;
+
+  final result = returnStructArgumentStruct1ByteInt(a0);
+
+  print("result = $result");
+
+  Expect.equals(a0.a0, result.a0);
+
+  free(a0.addressOf);
+}
+
+final returnStructArgumentInt32x8Struct1ByteInt =
+    ffiTestFunctions.lookupFunction<
+        Struct1ByteInt Function(Int32, Int32, Int32, Int32, Int32, Int32, Int32,
+            Int32, Struct1ByteInt),
+        Struct1ByteInt Function(int, int, int, int, int, int, int, int,
+            Struct1ByteInt)>("ReturnStructArgumentInt32x8Struct1ByteInt");
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed on stack on all ABIs.
+void testReturnStructArgumentInt32x8Struct1ByteInt() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  Struct1ByteInt a8 = allocate<Struct1ByteInt>().ref;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+  a5 = 6;
+  a6 = -7;
+  a7 = 8;
+  a8.a0 = -9;
+
+  final result = returnStructArgumentInt32x8Struct1ByteInt(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.equals(a8.a0, result.a0);
+
+  free(a8.addressOf);
+}
+
+final returnStructArgumentStruct8BytesHomogeneousFloat =
+    ffiTestFunctions.lookupFunction<
+            Struct8BytesHomogeneousFloat Function(Struct8BytesHomogeneousFloat),
+            Struct8BytesHomogeneousFloat Function(
+                Struct8BytesHomogeneousFloat)>(
+        "ReturnStructArgumentStruct8BytesHomogeneousFloat");
+
+/// Test that a struct passed in as argument can be returned.
+/// Especially for ffi callbacks.
+/// Struct is passed in float registers in most ABIs.
+void testReturnStructArgumentStruct8BytesHomogeneousFloat() {
+  Struct8BytesHomogeneousFloat a0 =
+      allocate<Struct8BytesHomogeneousFloat>().ref;
+
+  a0.a0 = -1.0;
+  a0.a1 = 2.0;
+
+  final result = returnStructArgumentStruct8BytesHomogeneousFloat(a0);
+
+  print("result = $result");
+
+  Expect.approxEquals(a0.a0, result.a0);
+  Expect.approxEquals(a0.a1, result.a1);
+
+  free(a0.addressOf);
+}
+
+final returnStructArgumentStruct20BytesHomogeneousInt32 =
+    ffiTestFunctions
+        .lookupFunction<
+                Struct20BytesHomogeneousInt32 Function(
+                    Struct20BytesHomogeneousInt32),
+                Struct20BytesHomogeneousInt32 Function(
+                    Struct20BytesHomogeneousInt32)>(
+            "ReturnStructArgumentStruct20BytesHomogeneousInt32");
+
+/// On arm64, both argument and return value are passed in by pointer.
+void testReturnStructArgumentStruct20BytesHomogeneousInt32() {
+  Struct20BytesHomogeneousInt32 a0 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  a0.a0 = -1;
+  a0.a1 = 2;
+  a0.a2 = -3;
+  a0.a3 = 4;
+  a0.a4 = -5;
+
+  final result = returnStructArgumentStruct20BytesHomogeneousInt32(a0);
+
+  print("result = $result");
+
+  Expect.equals(a0.a0, result.a0);
+  Expect.equals(a0.a1, result.a1);
+  Expect.equals(a0.a2, result.a2);
+  Expect.equals(a0.a3, result.a3);
+  Expect.equals(a0.a4, result.a4);
+
+  free(a0.addressOf);
+}
+
+final returnStructArgumentInt32x8Struct20BytesHomogeneou =
+    ffiTestFunctions.lookupFunction<
+            Struct20BytesHomogeneousInt32 Function(Int32, Int32, Int32, Int32,
+                Int32, Int32, Int32, Int32, Struct20BytesHomogeneousInt32),
+            Struct20BytesHomogeneousInt32 Function(int, int, int, int, int, int,
+                int, int, Struct20BytesHomogeneousInt32)>(
+        "ReturnStructArgumentInt32x8Struct20BytesHomogeneou");
+
+/// On arm64, both argument and return value are passed in by pointer.
+/// Ints exhaust registers, so that pointer is passed on stack.
+void testReturnStructArgumentInt32x8Struct20BytesHomogeneou() {
+  int a0;
+  int a1;
+  int a2;
+  int a3;
+  int a4;
+  int a5;
+  int a6;
+  int a7;
+  Struct20BytesHomogeneousInt32 a8 =
+      allocate<Struct20BytesHomogeneousInt32>().ref;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+  a3 = 4;
+  a4 = -5;
+  a5 = 6;
+  a6 = -7;
+  a7 = 8;
+  a8.a0 = -9;
+  a8.a1 = 10;
+  a8.a2 = -11;
+  a8.a3 = 12;
+  a8.a4 = -13;
+
+  final result = returnStructArgumentInt32x8Struct20BytesHomogeneou(
+      a0, a1, a2, a3, a4, a5, a6, a7, a8);
+
+  print("result = $result");
+
+  Expect.equals(a8.a0, result.a0);
+  Expect.equals(a8.a1, result.a1);
+  Expect.equals(a8.a2, result.a2);
+  Expect.equals(a8.a3, result.a3);
+  Expect.equals(a8.a4, result.a4);
+
+  free(a8.addressOf);
+}
+
+final returnStructAlignmentInt16 = ffiTestFunctions.lookupFunction<
+    StructAlignmentInt16 Function(Int8, Int16, Int8),
+    StructAlignmentInt16 Function(int, int, int)>("ReturnStructAlignmentInt16");
+
+/// Test alignment and padding of 16 byte int within struct.
+void testReturnStructAlignmentInt16() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStructAlignmentInt16(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStructAlignmentInt32 = ffiTestFunctions.lookupFunction<
+    StructAlignmentInt32 Function(Int8, Int32, Int8),
+    StructAlignmentInt32 Function(int, int, int)>("ReturnStructAlignmentInt32");
+
+/// Test alignment and padding of 32 byte int within struct.
+void testReturnStructAlignmentInt32() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStructAlignmentInt32(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
+
+final returnStructAlignmentInt64 = ffiTestFunctions.lookupFunction<
+    StructAlignmentInt64 Function(Int8, Int64, Int8),
+    StructAlignmentInt64 Function(int, int, int)>("ReturnStructAlignmentInt64");
+
+/// Test alignment and padding of 64 byte int within struct.
+void testReturnStructAlignmentInt64() {
+  int a0;
+  int a1;
+  int a2;
+
+  a0 = -1;
+  a1 = 2;
+  a2 = -3;
+
+  final result = returnStructAlignmentInt64(a0, a1, a2);
+
+  print("result = $result");
+
+  Expect.equals(a0, result.a0);
+  Expect.equals(a1, result.a1);
+  Expect.equals(a2, result.a2);
+}
diff --git a/tests/ffi_2/generator/c_types.dart b/tests/ffi_2/generator/c_types.dart
new file mode 100644
index 0000000..f2948fa
--- /dev/null
+++ b/tests/ffi_2/generator/c_types.dart
@@ -0,0 +1,299 @@
+// Copyright (c) 2020, 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.
+
+import 'utils.dart';
+
+const int8 = FundamentalType(PrimitiveType.int8);
+const int16 = FundamentalType(PrimitiveType.int16);
+const int32 = FundamentalType(PrimitiveType.int32);
+const int64 = FundamentalType(PrimitiveType.int64);
+const uint8 = FundamentalType(PrimitiveType.uint8);
+const uint16 = FundamentalType(PrimitiveType.uint16);
+const uint32 = FundamentalType(PrimitiveType.uint32);
+const uint64 = FundamentalType(PrimitiveType.uint64);
+const intptr = FundamentalType(PrimitiveType.intptr);
+const float = FundamentalType(PrimitiveType.float);
+const double_ = FundamentalType(PrimitiveType.double_);
+
+enum PrimitiveType {
+  int8,
+  int16,
+  int32,
+  int64,
+  uint8,
+  uint16,
+  uint32,
+  uint64,
+  intptr,
+  float,
+  double_,
+}
+
+const primitiveNames = [
+  "int8",
+  "int16",
+  "int32",
+  "int64",
+  "uint8",
+  "uint16",
+  "uint32",
+  "uint64",
+  "intptr",
+  "float",
+  "double",
+];
+
+const intptrSize = -1;
+const primitiveSizesInBytes = [1, 2, 4, 8, 1, 2, 4, 8, intptrSize, 4, 8];
+
+abstract class CType {
+  String get cType;
+  String get dartCType;
+  String get dartType;
+  String get dartStructFieldAnnotation;
+
+  /// Has a known [size] that is the same for all architectures.
+  bool get hasSize;
+
+  /// Get a size in bytes that is the same on all architectures.
+  int get size;
+
+  String toString() => dartCType;
+
+  const CType();
+}
+
+class FundamentalType extends CType {
+  final PrimitiveType primitive;
+
+  const FundamentalType(this.primitive);
+
+  bool get isFloatingPoint =>
+      primitive == PrimitiveType.float || primitive == PrimitiveType.double_;
+  bool get isInteger => !isFloatingPoint;
+  bool get isUnsigned =>
+      primitive == PrimitiveType.uint8 ||
+      primitive == PrimitiveType.uint16 ||
+      primitive == PrimitiveType.uint32 ||
+      primitive == PrimitiveType.uint64;
+  bool get isSigned => !isUnsigned;
+
+  String get name => primitiveNames[primitive.index];
+
+  String get cType => "${name}${isInteger ? "_t" : ""}";
+  String get dartCType => name.upperCaseFirst();
+  String get dartType => isInteger ? "int" : "double";
+  String get dartStructFieldAnnotation => "@${dartCType}()";
+  bool get hasSize => primitive != PrimitiveType.intptr;
+  int get size {
+    if (!hasSize) {
+      throw "Size unknown.";
+    }
+    return primitiveSizesInBytes[primitive.index];
+  }
+}
+
+class PointerType extends CType {
+  final CType pointerTo;
+
+  PointerType(this.pointerTo);
+
+  String get cType => "${pointerTo.cType}*";
+  String get dartCType => "Pointer<${pointerTo.dartCType}>";
+  String get dartType => "Pointer<${pointerTo.dartType}>";
+  String get dartStructFieldAnnotation => "";
+  bool get hasSize => false;
+  int get size => throw "Size unknown";
+}
+
+/// Used to give [StructType] fields and [FunctionType] arguments names.
+class Member {
+  final CType type;
+  final String name;
+
+  Member(this.type, this.name);
+
+  String dartStructField(bool nnbd) {
+    final modifier = nnbd ? "external" : "";
+    return "${type.dartStructFieldAnnotation} $modifier ${type.dartType} $name;";
+  }
+
+  String get cStructField => "${type.cType} $name;";
+
+  String toString() => "$type $name";
+}
+
+List<Member> generateMemberNames(List<CType> memberTypes) {
+  int index = 0;
+  List<Member> result = [];
+  for (final type in memberTypes) {
+    result.add(Member(type, "a$index"));
+    index++;
+  }
+  return result;
+}
+
+class StructType extends CType {
+  final List<Member> members;
+
+  /// To disambiguate same size structs.
+  final String suffix;
+
+  StructType(List<CType> memberTypes)
+      : this.members = generateMemberNames(memberTypes),
+        this.suffix = "";
+  StructType.disambiguate(List<CType> memberTypes, this.suffix)
+      : this.members = generateMemberNames(memberTypes);
+
+  List<CType> get memberTypes => members.map((a) => a.type).toList();
+
+  String get cType => name;
+  String get dartCType => name;
+  String get dartType => name;
+  String get dartStructFieldAnnotation => "";
+
+  bool get hasSize =>
+      !memberTypes.map((e) => e.hasSize).contains(false) && !hasPadding;
+  int get size => memberTypes.fold(0, (int acc, e) => acc + e.size);
+
+  /// Rough approximation, to not redo all ABI logic here.
+  bool get hasPadding =>
+      members.length < 2 ? false : members[0].type.size < members[1].type.size;
+
+  bool get hasNestedStructs =>
+      members.map((e) => e.type is StructType).contains(true);
+
+  /// All members have the same type.
+  bool get isHomogeneous => memberTypes.toSet().length == 1;
+
+  /// All members have a floating point type.
+  bool get isOnlyFloatingPoint => !memberTypes.map((e) {
+        if (e is FundamentalType) {
+          return e.isFloatingPoint;
+        }
+        if (e is StructType) {
+          return e.isOnlyFloatingPoint;
+        }
+      }).contains(false);
+
+  /// All members have a integer type.
+  bool get isOnlyInteger => !memberTypes.map((e) {
+        if (e is FundamentalType) {
+          return e.isInteger;
+        }
+        if (e is StructType) {
+          return e.isOnlyInteger;
+        }
+      }).contains(false);
+
+  bool get isMixed => !isOnlyInteger && !isOnlyFloatingPoint;
+
+  String get name {
+    String result = "Struct";
+    if (hasSize) {
+      result += "${size}Byte" + (size != 1 ? "s" : "");
+    }
+    if (hasNestedStructs) {
+      result += "Nested";
+    }
+    if (members.length == 0) {
+      // No suffix.
+    } else if (hasPadding) {
+      result += "Alignment${memberTypes[1].dartCType}";
+    } else if (isHomogeneous && members.length > 1 && !hasNestedStructs) {
+      result += "Homogeneous${memberTypes.first.dartCType}";
+    } else if (isOnlyFloatingPoint) {
+      result += "Float";
+    } else if (isOnlyInteger) {
+      result += "Int";
+    } else {
+      result += "Mixed";
+    }
+    result += suffix;
+    return result;
+  }
+}
+
+class FunctionType extends CType {
+  final List<Member> arguments;
+  final CType returnValue;
+  final String reason;
+
+  List<CType> get argumentTypes => arguments.map((a) => a.type).toList();
+
+  FunctionType(List<CType> argumentTypes, this.returnValue, this.reason)
+      : this.arguments = generateMemberNames(argumentTypes);
+
+  String get cType =>
+      throw "Are not represented without function or variable name in C.";
+
+  String get dartCType {
+    final argumentsDartCType = argumentTypes.map((e) => e.dartCType).join(", ");
+    return "${returnValue.dartCType} Function($argumentsDartCType)";
+  }
+
+  String get dartType {
+    final argumentsDartType = argumentTypes.map((e) => e.dartType).join(", ");
+    return "${returnValue.dartType} Function($argumentsDartType)";
+  }
+
+  String get dartStructFieldAnnotation => throw "No nested function pointers.";
+
+  bool get hasSize => false;
+  int get size => throw "Unknown size.";
+
+  /// Group consecutive [arguments] by same type.
+  ///
+  /// Used for naming.
+  List<List<Member>> get argumentsGrouped {
+    List<List<Member>> result = [];
+    for (final a in arguments) {
+      if (result.isEmpty) {
+        result.add([a]);
+      } else if (result.last.first.type.dartCType == a.type.dartCType) {
+        result.last.add(a);
+      } else {
+        result.add([a]);
+      }
+    }
+    return result;
+  }
+
+  /// A suitable name based on the signature.
+  String get cName {
+    String result = "";
+    if (arguments.containsStructs && returnValue is FundamentalType) {
+      result = "Pass";
+    } else if (returnValue is StructType &&
+        argumentTypes.contains(returnValue)) {
+      result = "ReturnStructArgument";
+    } else if (returnValue is StructType) {
+      if (arguments.length == (returnValue as StructType).members.length) {
+        return "Return${returnValue.dartCType}";
+      }
+    } else {
+      result = "Uncategorized";
+    }
+
+    for (final group in argumentsGrouped) {
+      result += group.first.type.dartCType;
+      if (group.length > 1) {
+        result += "x${group.length}";
+      }
+    }
+    return result.limitTo(50);
+  }
+
+  String get dartTestName => "test$cName";
+
+  String get dartName => cName.lowerCaseFirst();
+
+  /// Only valid for [TestType.structReturnArgument].
+  Member get structReturnArgument =>
+      arguments.firstWhere((a) => a.type == returnValue);
+}
+
+extension MemberList on List<Member> {
+  bool get containsStructs => map((m) => m.type is StructType).contains(true);
+}
diff --git a/tests/ffi_2/generator/structs_by_value_tests_confguration.dart b/tests/ffi_2/generator/structs_by_value_tests_confguration.dart
new file mode 100644
index 0000000..487a68e
--- /dev/null
+++ b/tests/ffi_2/generator/structs_by_value_tests_confguration.dart
@@ -0,0 +1,373 @@
+// Copyright (c) 2020, 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.
+
+import 'c_types.dart';
+
+final functions = [
+  FunctionType(List.filled(10, struct1byteInt), int64, """
+Smallest struct with data.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct3bytesInt), int64, """
+Not a multiple of word size, not a power of two.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct4bytesInt), int64, """
+Exactly word size on 32-bit architectures.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct7bytesInt), int64, """
+Sub word size on 64 bit architectures.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct8bytesInt), int64, """
+Exactly word size struct on 64bit architectures.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct8bytesFloat), float, """
+Arguments passed in FP registers as long as they fit.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct8BytesMixed), float, """
+On x64, arguments go in int registers because it is not only float.
+10 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct9bytesInt), int64, """
+Argument is a single byte over a multiple of word size.
+10 struct arguments will exhaust available registers.
+Tests upper bytes in the integer registers that are partly filled.
+Tests stack alignment of non word size stack arguments."""),
+  FunctionType(List.filled(10, struct9bytesInt2), int64, """
+Argument is a single byte over a multiple of word size.
+10 struct arguments will exhaust available registers.
+Struct only has 1-byte aligned fields to test struct alignment itself.
+"""),
+  FunctionType(List.filled(6, struct12bytesFloat), float, """
+Arguments in FPU registers on arm hardfp and arm64.
+Struct arguments will exhaust available registers, and leave some empty.
+The last argument is to test whether arguments are backfilled."""),
+  FunctionType(List.filled(5, struct16bytesFloat), float, """
+On Linux x64 argument is transferred on stack because it is over 16 bytes.
+Arguments in FPU registers on arm hardfp and arm64.
+5 struct arguments will exhaust available registers."""),
+  FunctionType(List.filled(10, struct16bytesMixed), double_, """
+On x64, arguments are split over FP and int registers.
+On x64, it will exhaust the integer registers with the 6th argument.
+The rest goes on the stack.
+On arm, arguments are 8 byte aligned."""),
+  FunctionType(List.filled(10, struct16bytesMixed2), float, """
+On x64, arguments are split over FP and int registers.
+On x64, it will exhaust the integer registers with the 6th argument.
+The rest goes on the stack.
+On arm, arguments are 4 byte aligned."""),
+  FunctionType(List.filled(10, struct17bytesInt), int64, """
+Arguments are passed as pointer to copy on arm64.
+Tests that the memory allocated for copies are rounded up to word size."""),
+  FunctionType(List.filled(10, struct19bytesInt), int64, """
+The minimum alignment of this struct is only 1 byte based on its fields.
+Test that the memory backing these structs is extended to the right size.
+"""),
+  FunctionType(List.filled(10, struct20bytesInt), int32, """
+Argument too big to go into integer registers on arm64.
+The arguments are passed as pointers to copies.
+The amount of arguments exhausts the number of integer registers, such that
+pointers to copies are also passed on the stack."""),
+  FunctionType(
+      [struct20bytesFloat],
+      float,
+      """
+Argument too big to go into FPU registers in hardfp and arm64."""),
+  FunctionType(List.filled(5, struct32bytesDouble), double_, """
+Arguments in FPU registers on arm64.
+5 struct arguments will exhaust available registers."""),
+  FunctionType(
+      [struct40bytesDouble],
+      double_,
+      """
+Argument too big to go into FPU registers in arm64."""),
+  FunctionType(
+      [struct1024bytesInt],
+      uint64,
+      """
+Test 1kb struct."""),
+  FunctionType(
+      [
+        float,
+        struct16bytesFloat,
+        float,
+        struct16bytesFloat,
+        float,
+        struct16bytesFloat,
+        float,
+        struct16bytesFloat,
+        float
+      ],
+      float,
+      """
+Tests the alignment of structs in FPU registers and backfilling."""),
+  FunctionType(
+      [
+        float,
+        struct32bytesDouble,
+        float,
+        struct32bytesDouble,
+        float,
+        struct32bytesDouble,
+        float,
+        struct32bytesDouble,
+        float
+      ],
+      double_,
+      """
+Tests the alignment of structs in FPU registers and backfilling."""),
+  FunctionType(
+      [
+        int8,
+        struct16bytesMixed,
+        int8,
+        struct16bytesMixed,
+        int8,
+        struct16bytesMixed,
+        int8,
+        struct16bytesMixed,
+        int8
+      ],
+      double_,
+      """
+Tests the alignment of structs in integers registers and on the stack.
+Arm32 aligns this struct at 8.
+Also, arm32 allocates the second struct partially in registers, partially
+on stack.
+Test backfilling of integer registers."""),
+  FunctionType(
+      [
+        double_,
+        double_,
+        double_,
+        double_,
+        double_,
+        double_,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        int32,
+      ],
+      double_,
+      """
+On Linux x64, it will exhaust xmm registers first, after 6 doubles and 2
+structs. The rest of the structs will go on the stack.
+The int will be backfilled into the int register."""),
+  FunctionType(
+      [
+        int32,
+        int32,
+        int32,
+        int32,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        struct16bytesMixed,
+        double_,
+      ],
+      double_,
+      """
+On Linux x64, it will exhaust int registers first.
+The rest of the structs will go on the stack.
+The double will be backfilled into the xmm register."""),
+  FunctionType(
+      [
+        struct40bytesDouble,
+        struct4bytesInt,
+        struct8bytesFloat,
+      ],
+      double_,
+      """
+On various architectures, first struct is allocated on stack.
+Check that the other two arguments are allocated on registers."""),
+  FunctionType(
+      [structAlignmentInt16],
+      int64,
+      """
+Test alignment and padding of 16 byte int within struct."""),
+  FunctionType(
+      [structAlignmentInt32],
+      int64,
+      """
+Test alignment and padding of 32 byte int within struct."""),
+  FunctionType(
+      [structAlignmentInt64],
+      int64,
+      """
+Test alignment and padding of 64 byte int within struct."""),
+  FunctionType(struct1byteInt.memberTypes, struct1byteInt, """
+Smallest struct with data."""),
+  FunctionType(struct3bytesInt.memberTypes, struct3bytesInt, """
+Smaller than word size return value on all architectures."""),
+  FunctionType(struct4bytesInt.memberTypes, struct4bytesInt, """
+Word size return value on 32 bit architectures.."""),
+  FunctionType(struct7bytesInt.memberTypes, struct7bytesInt, """
+Non-wordsize return value."""),
+  FunctionType(struct8bytesInt.memberTypes, struct8bytesInt, """
+Return value in integer registers on many architectures."""),
+  FunctionType(struct8bytesFloat.memberTypes, struct8bytesFloat, """
+Return value in FP registers on many architectures."""),
+  FunctionType(struct8BytesMixed.memberTypes, struct8BytesMixed, """
+Return value split over FP and integer register in x64."""),
+  FunctionType(struct9bytesInt.memberTypes, struct9bytesInt, """
+Return value in two integer registers on x64.
+The second register only contains a single byte."""),
+  FunctionType(struct9bytesInt2.memberTypes, struct9bytesInt2, """
+The minimum alignment of this struct is only 1 byte based on its fields.
+Test that the memory backing these structs is the right size and that
+dart:ffi trampolines do not write outside this size."""),
+  FunctionType(struct12bytesFloat.memberTypes, struct12bytesFloat, """
+Return value in FPU registers, but does not use all registers on arm hardfp
+and arm64."""),
+  FunctionType(struct16bytesFloat.memberTypes, struct16bytesFloat, """
+Return value in FPU registers on arm hardfp and arm64."""),
+  FunctionType(struct16bytesMixed.memberTypes, struct16bytesMixed, """
+Return value split over FP and integer register in x64."""),
+  FunctionType(struct16bytesMixed2.memberTypes, struct16bytesMixed2, """
+Return value split over FP and integer register in x64.
+The integer register contains half float half int."""),
+  FunctionType(struct17bytesInt.memberTypes, struct17bytesInt, """
+Rerturn value returned in preallocated space passed by pointer on most ABIs.
+Is non word size on purpose, to test that structs are rounded up to word size
+on all ABIs."""),
+  FunctionType(struct19bytesInt.memberTypes, struct19bytesInt, """
+The minimum alignment of this struct is only 1 byte based on its fields.
+Test that the memory backing these structs is the right size and that
+dart:ffi trampolines do not write outside this size."""),
+  FunctionType(struct20bytesInt.memberTypes, struct20bytesInt, """
+Return value too big to go in cpu registers on arm64."""),
+  FunctionType(struct20bytesFloat.memberTypes, struct20bytesFloat, """
+Return value too big to go in FPU registers on x64, arm hardfp and arm64."""),
+  FunctionType(struct32bytesDouble.memberTypes, struct32bytesDouble, """
+Return value in FPU registers on arm64."""),
+  FunctionType(struct40bytesDouble.memberTypes, struct40bytesDouble, """
+Return value too big to go in FPU registers on arm64."""),
+  FunctionType(struct1024bytesInt.memberTypes, struct1024bytesInt, """
+Test 1kb struct."""),
+  FunctionType(
+      [struct1byteInt],
+      struct1byteInt,
+      """
+Test that a struct passed in as argument can be returned.
+Especially for ffi callbacks.
+Struct is passed in int registers in most ABIs."""),
+  FunctionType(
+      [int32, int32, int32, int32, int32, int32, int32, int32, struct1byteInt],
+      struct1byteInt,
+      """
+Test that a struct passed in as argument can be returned.
+Especially for ffi callbacks.
+Struct is passed on stack on all ABIs."""),
+  FunctionType(
+      [struct8bytesFloat],
+      struct8bytesFloat,
+      """
+Test that a struct passed in as argument can be returned.
+Especially for ffi callbacks.
+Struct is passed in float registers in most ABIs."""),
+  FunctionType(
+      [struct20bytesInt],
+      struct20bytesInt,
+      """
+On arm64, both argument and return value are passed in by pointer."""),
+  FunctionType(
+      [
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        int32,
+        struct20bytesInt
+      ],
+      struct20bytesInt,
+      """
+On arm64, both argument and return value are passed in by pointer.
+Ints exhaust registers, so that pointer is passed on stack."""),
+  FunctionType(structAlignmentInt16.memberTypes, structAlignmentInt16, """
+Test alignment and padding of 16 byte int within struct."""),
+  FunctionType(structAlignmentInt32.memberTypes, structAlignmentInt32, """
+Test alignment and padding of 32 byte int within struct."""),
+  FunctionType(structAlignmentInt64.memberTypes, structAlignmentInt64, """
+Test alignment and padding of 64 byte int within struct."""),
+];
+
+final structs = [
+  struct0bytes,
+  struct1byteInt,
+  struct3bytesInt,
+  struct4bytesInt,
+  struct7bytesInt,
+  struct8bytesInt,
+  struct8bytesFloat,
+  struct8BytesMixed,
+  struct9bytesInt,
+  struct9bytesInt2,
+  struct12bytesFloat,
+  struct16bytesFloat,
+  struct16bytesMixed,
+  struct16bytesMixed2,
+  struct17bytesInt,
+  struct19bytesInt,
+  struct20bytesInt,
+  struct20bytesFloat,
+  struct32bytesDouble,
+  struct40bytesDouble,
+  struct1024bytesInt,
+  structAlignmentInt16,
+  structAlignmentInt32,
+  structAlignmentInt64,
+];
+
+/// Using empty structs is undefined behavior in C.
+final struct0bytes = StructType([]);
+
+final struct1byteInt = StructType([int8]);
+final struct3bytesInt = StructType([int16, int8]);
+final struct4bytesInt = StructType([int16, int16]);
+final struct7bytesInt = StructType([int32, int16, int8]);
+final struct8bytesInt = StructType([int16, int16, int32]);
+final struct8bytesFloat = StructType([float, float]);
+final struct8BytesMixed = StructType([float, int16, int16]);
+final struct9bytesInt = StructType([int64, int8]);
+final struct9bytesInt2 = StructType.disambiguate(List.filled(9, uint8), "2");
+final struct12bytesFloat = StructType([float, float, float]);
+
+/// The largest homogenous float that goes into FPU registers on softfp and
+/// arm64.
+final struct16bytesFloat = StructType([float, float, float, float]);
+
+/// This struct will be 8 byte aligned on arm.
+final struct16bytesMixed = StructType([double_, int64]);
+
+/// This struct will be 4 byte aligned on arm.
+final struct16bytesMixed2 =
+    StructType.disambiguate([float, float, float, int32], "2");
+
+final struct17bytesInt = StructType([int64, int64, int8]);
+
+/// This struct has only 1 byte field-alignmnent requirements.
+final struct19bytesInt = StructType(List.filled(19, uint8));
+
+/// The first homogenous integer struct that does not go into registers
+/// anymore on arm64.
+final struct20bytesInt = StructType([int32, int32, int32, int32, int32]);
+
+/// The first homogenous float that does not go into FPU registers anymore on
+/// softfp and arm64.
+final struct20bytesFloat = StructType([float, float, float, float, float]);
+
+/// Largest homogenous doubles in arm64 that goes into FPU registers.
+final struct32bytesDouble = StructType([double_, double_, double_, double_]);
+
+/// The first homogenous doubles that does not go into FPU registers anymore on
+/// arm64.
+final struct40bytesDouble =
+    StructType([double_, double_, double_, double_, double_]);
+
+final struct1024bytesInt = StructType(List.filled(128, uint64));
+
+final structAlignmentInt16 = StructType([int8, int16, int8]);
+final structAlignmentInt32 = StructType([int8, int32, int8]);
+final structAlignmentInt64 = StructType([int8, int64, int8]);
diff --git a/tests/ffi_2/generator/structs_by_value_tests_generator.dart b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
new file mode 100644
index 0000000..e233753
--- /dev/null
+++ b/tests/ffi_2/generator/structs_by_value_tests_generator.dart
@@ -0,0 +1,930 @@
+// Copyright (c) 2020, 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.
+
+import 'dart:io';
+
+import 'c_types.dart';
+import 'structs_by_value_tests_confguration.dart';
+import 'utils.dart';
+
+/// The test type determines how to convert the arguments into return values
+/// such that the caller knows what to check.
+enum TestType {
+  /// Tested by getting all the individual fields out of the structs and
+  /// summing their values.
+  structArguments,
+
+  /// Tested by passing assigning the arguments to the struct fields.
+  structReturn,
+
+  /// Tested by returning the struct passed in.
+  structReturnArgument,
+}
+
+extension on FunctionType {
+  TestType get testType {
+    if (arguments.containsStructs && returnValue is FundamentalType) {
+      return TestType.structArguments;
+    }
+    if (returnValue is StructType && argumentTypes.contains(returnValue)) {
+      return TestType.structReturnArgument;
+    }
+    if (returnValue is StructType) {
+      if (arguments.length == (returnValue as StructType).members.length) {
+        return TestType.structReturn;
+      }
+    }
+    throw Exception("Unknown test type: $this");
+  }
+}
+
+/// We use the class structure as an algebraic data type in order to keep the
+/// relevant parts of the code generation closer together.
+extension on CType {
+  /// The part of the cout expression after `std::cout` and before the `;`.
+  String coutExpression(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        if (this == uint8 || this == int8) {
+          return "<< static_cast<int>($variableName)";
+        }
+        return "<< $variableName";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.coutExpression("$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A statement recursively outputting all members.
+  String coutStatement(String variableName) {
+    final coutExpr = this.coutExpression(variableName);
+    return 'std::cout << "$variableName = " $coutExpr << "\\n";';
+  }
+}
+
+extension on List<Member> {
+  /// The part of the cout expression after `std::cout` and before the `;`.
+  String coutExpression([String namePrefix = ""]) {
+    String result = '<< "("';
+    result += this
+        .map((m) => m.type.coutExpression("$namePrefix${m.name}"))
+        .join('<< ", "');
+    result += '<< ")"';
+    return result.trimCouts();
+  }
+}
+
+extension on CType {
+  /// A list of statements adding all members recurisvely to `result`.
+  ///
+  /// Both valid in Dart and C.
+  String addToResultStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "result += $variableName;\n";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.addToResultStatements("$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of statements adding all members recurisvely to `result`.
+  ///
+  /// Both valid in Dart and C.
+  String addToResultStatements([String namePrefix = ""]) {
+    return map((m) => m.type.addToResultStatements("$namePrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// A list of statements recursively assigning all members with [a].
+  ///
+  /// Both valid in Dart and C.
+  String assignValueStatements(ArgumentValueAssigner a, String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        return "$variableName = ${a.nextValue(this_)};\n";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.assignValueStatements(a, "$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A list of statements recursively coping all members from [source].
+  ///
+  /// Both valid in Dart and C.
+  String copyValueStatements(String source, String destination) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "$destination = $source;\n";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.copyValueStatements("$source.", "$destination.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of statements recursively assigning all members with [a].
+  ///
+  /// Both valid in Dart and C.
+  String assignValueStatements(ArgumentValueAssigner a,
+      [String namePrefix = ""]) {
+    return map((m) => m.type.assignValueStatements(a, "$namePrefix${m.name}"))
+        .join();
+  }
+
+  /// A list of statements recursively coping all members from [source].
+  ///
+  /// Both valid in Dart and C.
+  String copyValueStatements([sourcePrefix = "", destinationPrefix = ""]) {
+    return map((m) => m.type.copyValueStatements(
+        "$sourcePrefix${m.name}", "$destinationPrefix${m.name}")).join();
+  }
+}
+
+/// A helper class that assigns values to fundamental types.
+///
+/// Also keeps track of a sum of all values, to be used for testing the result.
+class ArgumentValueAssigner {
+  int i = 1;
+  int sum = 0;
+  String nextValue(FundamentalType type) {
+    int argumentValue = i;
+    i++;
+    if (type.isSigned && i % 2 == 0) {
+      argumentValue = -argumentValue;
+    }
+    sum += argumentValue;
+    if (type.isFloatingPoint) {
+      return argumentValue.toDouble().toString();
+    } else {
+      return argumentValue.toString();
+    }
+  }
+
+  String sumValue(FundamentalType type) {
+    if (type.isFloatingPoint) {
+      return sum.toDouble().toString();
+    } else {
+      return sum.toString();
+    }
+  }
+}
+
+extension on CType {
+  /// A list of Dart statements recursively allocating all members.
+  String dartAllocateStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "${dartType} ${variableName};\n";
+
+      case StructType:
+        return "${dartType} ${variableName} = allocate<$dartType>().ref;\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A list of Dart statements allocating as zero or nullptr.
+  String dartAllocateZeroStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "${dartType} ${variableName} = 0;\n";
+        }
+        return "${dartType} ${variableName} = 0.0;\n";
+
+      case StructType:
+        return "${dartType} ${variableName} = ${dartType}();\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of Dart statements recursively allocating all members.
+  String dartAllocateStatements([String namePrefix = ""]) {
+    return map((m) => m.type.dartAllocateStatements("$namePrefix${m.name}"))
+        .join();
+  }
+
+  /// A list of Dart statements as zero or nullptr.
+  String dartAllocateZeroStatements([String namePrefix = ""]) {
+    return map((m) => m.type.dartAllocateZeroStatements("$namePrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// A list of Dart statements recursively freeing all members.
+  String dartFreeStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return "";
+
+      case StructType:
+        return "free($variableName.addressOf);\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of Dart statements recursively freeing all members.
+  String dartFreeStatements([String namePrefix = ""]) {
+    return map((m) => m.type.dartFreeStatements("$namePrefix${m.name}")).join();
+  }
+}
+
+extension on CType {
+  /// A list of C statements recursively allocating all members.
+  String cAllocateStatements(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+      case StructType:
+        return "${cType} ${variableName};\n";
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of C statements recursively allocating all members.
+  String cAllocateStatements([String namePrefix = ""]) {
+    return map((m) => m.type.cAllocateStatements("$namePrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// A list of Dart statements recursively checking all members.
+  String dartExpectsStatements(String expected, String actual) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "Expect.equals(${expected}, ${actual});";
+        }
+        assert(this_.isFloatingPoint);
+        return "Expect.approxEquals(${expected}, ${actual});";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.dartExpectsStatements("$expected.", "$actual.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of Dart statements recursively checking all members.
+  String dartExpectsStatements(
+      [String expectedPrefix = "", String actualPrefix = ""]) {
+    return map((m) => m.type.dartExpectsStatements(
+        "$expectedPrefix${m.name}", "$actualPrefix${m.name}")).join();
+  }
+}
+
+extension on CType {
+  /// A list of C statements recursively checking all members.
+  String cExpectsStatements(String expected, String actual) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "CHECK_EQ(${expected}, ${actual});";
+        }
+        assert(this_.isFloatingPoint);
+        return "CHECK_APPROX(${expected}, ${actual});";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.cExpectsStatements("$expected.", "$actual.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+
+  /// A list of C statements recursively checking all members for zero.
+  String cExpectsZeroStatements(String actual) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        final this_ = this as FundamentalType;
+        if (this_.isInteger) {
+          return "CHECK_EQ(0, ${actual});";
+        }
+        assert(this_.isFloatingPoint);
+        return "CHECK_APPROX(0.0, ${actual});";
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.cExpectsZeroStatements("$actual.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// A list of C statements recursively checking all members.
+  String cExpectsStatements(
+      [String expectedPrefix = "", String actualPrefix = ""]) {
+    return map((m) => m.type.cExpectsStatements(
+        "$expectedPrefix${m.name}", "$actualPrefix${m.name}")).join();
+  }
+
+  /// A list of C statements recursively checking all members for zero.
+  String cExpectsZeroStatements([String actualPrefix = ""]) {
+    return map((m) => m.type.cExpectsZeroStatements("$actualPrefix${m.name}"))
+        .join();
+  }
+}
+
+extension on CType {
+  /// Expression denoting the first FundamentalType field.
+  ///
+  /// Both valid in Dart and C.
+  String firstArgumentName(String variableName) {
+    switch (this.runtimeType) {
+      case FundamentalType:
+        return variableName;
+
+      case StructType:
+        final this_ = this as StructType;
+        return this_.members.firstArgumentName("$variableName.");
+    }
+
+    throw Exception("Not implemented for ${this.runtimeType}");
+  }
+}
+
+extension on List<Member> {
+  /// Expression denoting the first FundamentalType field.
+  ///
+  /// Both valid in Dart and C.
+  String firstArgumentName([String prefix = ""]) {
+    return this[0].type.firstArgumentName("$prefix${this[0].name}");
+  }
+}
+
+extension on StructType {
+  String dartClass(bool nnbd) {
+    String dartFields = "";
+    for (final member in members) {
+      dartFields += "${member.dartStructField(nnbd)}\n\n";
+    }
+    String toStringBody = members.map((m) => "\$\{${m.name}\}").join(", ");
+    return """
+    class $name extends Struct {
+      $dartFields
+
+      String toString() => "($toStringBody)";
+    }
+    """;
+  }
+
+  String get cDefinition {
+    String cFields = "";
+    for (final member in members) {
+      cFields += "  ${member.cStructField}\n";
+    }
+    return """
+    struct $name {
+      $cFields
+    };
+
+    """;
+  }
+}
+
+extension on FunctionType {
+  String get dartCallCode {
+    final a = ArgumentValueAssigner();
+    final assignValues = arguments.assignValueStatements(a);
+    final argumentFrees = arguments.dartFreeStatements();
+
+    final argumentNames = arguments.map((e) => e.name).join(", ");
+
+    String expects;
+    switch (testType) {
+      case TestType.structArguments:
+        // Check against sum value.
+        final expectedResult = a.sumValue(returnValue as FundamentalType);
+        expects = returnValue.dartExpectsStatements(expectedResult, "result");
+        break;
+      case TestType.structReturn:
+        // Check against input arguments.
+        expects = arguments.dartExpectsStatements("", "result.");
+        break;
+      case TestType.structReturnArgument:
+        expects = returnValue.dartExpectsStatements(
+            structReturnArgument.name, "result");
+        break;
+    }
+
+    return """
+    final $dartName =
+      ffiTestFunctions.lookupFunction<$dartCType, $dartType>("$cName");
+
+    ${reason.makeDartDocComment()}
+    void $dartTestName() {
+      ${arguments.dartAllocateStatements()}
+
+      ${assignValues}
+
+      final result = $dartName($argumentNames);
+
+      print("result = \$result");
+
+      $expects
+
+      $argumentFrees
+    }
+    """;
+  }
+
+  String dartCallbackCode(bool nnbd) {
+    final argumentss =
+        arguments.map((a) => "${a.type.dartType} ${a.name}").join(", ");
+
+    final prints = arguments.map((a) => "\$\{${a.name}\}").join(", ");
+
+    String buildReturnValue = "";
+    switch (testType) {
+      case TestType.structArguments:
+        // Sum all input values.
+        buildReturnValue = """
+        ${returnValue.dartType} result = 0;
+
+        ${arguments.addToResultStatements('${dartName}_')}
+        """;
+        break;
+      case TestType.structReturn:
+        // Allocate a struct.
+        buildReturnValue = """
+        ${returnValue.dartType} result = allocate<${returnValue.dartType}>().ref;
+
+        ${arguments.copyValueStatements("${dartName}_", "result.")}
+        """;
+        break;
+      case TestType.structReturnArgument:
+        buildReturnValue = """
+        ${returnValue.cType} result = ${dartName}_${structReturnArgument.name};
+        """;
+        break;
+    }
+
+    final globals = arguments.dartAllocateZeroStatements("${dartName}_");
+
+    final copyToGlobals =
+        arguments.map((a) => '${dartName}_${a.name} = ${a.name};').join("\n");
+
+    // Simulate assigning values the same way as in C, so that we know what the
+    // final return value should be.
+    final a = ArgumentValueAssigner();
+    arguments.assignValueStatements(a);
+    String afterCallbackExpects = "";
+    String afterCallbackFrees = "";
+    switch (testType) {
+      case TestType.structArguments:
+        // Check that the input structs are still available.
+        // Check against sum value.
+        final expectedResult = a.sumValue(returnValue as FundamentalType);
+        afterCallbackExpects =
+            returnValue.dartExpectsStatements(expectedResult, "result");
+        break;
+      case TestType.structReturn:
+        // We're passing allocating structs in [buildReturnValue].
+        afterCallbackFrees =
+            returnValue.dartFreeStatements("${dartName}Result");
+        break;
+      case TestType.structReturnArgument:
+        break;
+    }
+
+    String returnNull = "";
+    if (!nnbd) {
+      returnNull = """
+      if (${arguments.firstArgumentName()} == $returnNullValue) {
+        print("returning null!");
+        return null;
+      }
+      """;
+    }
+
+    return """
+    typedef ${cName}Type = $dartCType;
+
+    // Global variables to be able to test inputs after callback returned.
+    $globals
+
+    // Result variable also global, so we can delete it after the callback.
+    ${returnValue.dartAllocateZeroStatements("${dartName}Result")}
+
+    ${returnValue.dartType} ${dartName}CalculateResult() {
+      $buildReturnValue
+
+      ${dartName}Result = result;
+
+      return result;
+    }
+
+    ${reason.makeDartDocComment()}
+    ${returnValue.dartType} $dartName($argumentss) {
+      print("$dartName($prints)");
+
+      // In legacy mode, possibly return null.
+      $returnNull
+
+      // In both nnbd and legacy mode, possibly throw.
+      if (${arguments.firstArgumentName()} == $throwExceptionValue ||
+          ${arguments.firstArgumentName()} == $returnNullValue) {
+        print("throwing!");
+        throw Exception("$cName throwing on purpuse!");
+      }
+
+      $copyToGlobals
+
+      final result = ${dartName}CalculateResult();
+
+      print(\"result = \$result\");
+
+      return result;
+    }
+
+    void ${dartName}AfterCallback() {
+      $afterCallbackFrees
+
+      final result = ${dartName}CalculateResult();
+
+      print(\"after callback result = \$result\");
+
+      $afterCallbackExpects
+
+      $afterCallbackFrees
+    }
+
+    """;
+  }
+
+  String get dartCallbackTestConstructor {
+    String exceptionalReturn = "";
+    if (returnValue is FundamentalType) {
+      if ((returnValue as FundamentalType).isFloatingPoint) {
+        exceptionalReturn = ", 0.0";
+      } else {
+        exceptionalReturn = ", 0";
+      }
+    }
+    return """
+    CallbackTest.withCheck("$cName",
+      Pointer.fromFunction<${cName}Type>($dartName$exceptionalReturn),
+      ${dartName}AfterCallback),
+    """;
+  }
+
+  String get cCallCode {
+    String body = "";
+    switch (testType) {
+      case TestType.structArguments:
+        body = """
+        ${returnValue.cType} result = 0;
+
+        ${arguments.addToResultStatements()}
+        """;
+        break;
+      case TestType.structReturn:
+        body = """
+        ${returnValue.cType} result;
+
+        ${arguments.copyValueStatements("", "result.")}
+        """;
+        break;
+      case TestType.structReturnArgument:
+        body = """
+        ${returnValue.cType} result = ${structReturnArgument.name};
+        """;
+        break;
+    }
+
+    final argumentss =
+        arguments.map((e) => "${e.type.cType} ${e.name}").join(", ");
+
+    return """
+    // Used for testing structs by value.
+    ${reason.makeCComment()}
+    DART_EXPORT ${returnValue.cType} $cName($argumentss) {
+      std::cout << \"$cName\" ${arguments.coutExpression()} << \"\\n\";
+
+      $body
+
+      ${returnValue.coutStatement("result")}
+
+      return result;
+    }
+
+    """;
+  }
+
+  String get cCallbackCode {
+    final a = ArgumentValueAssigner();
+    final argumentAllocations = arguments.cAllocateStatements();
+    final assignValues = arguments.assignValueStatements(a);
+
+    final argumentss =
+        arguments.map((e) => "${e.type.cType} ${e.name}").join(", ");
+
+    final argumentNames = arguments.map((e) => e.name).join(", ");
+
+    String expects = "";
+    String expectsZero = "";
+    switch (testType) {
+      case TestType.structArguments:
+        // Check against sum value.
+        final returnValue_ = returnValue as FundamentalType;
+        final expectedResult = a.sumValue(returnValue_);
+        expects = returnValue.cExpectsStatements(expectedResult, "result");
+
+        expectsZero = returnValue.cExpectsZeroStatements("result");
+        break;
+      case TestType.structReturn:
+        // Check against input statements.
+        expects = arguments.cExpectsStatements("", "result.");
+
+        expectsZero = arguments.cExpectsZeroStatements("result.");
+        break;
+      case TestType.structReturnArgument:
+        // Check against input struct fields.
+        expects =
+            returnValue.cExpectsStatements(structReturnArgument.name, "result");
+
+        expectsZero = returnValue.cExpectsZeroStatements("result");
+        break;
+    }
+
+    return """
+    // Used for testing structs by value.
+    ${reason.makeCComment()}
+    DART_EXPORT intptr_t
+    Test$cName(
+        // NOLINTNEXTLINE(whitespace/parens)
+        ${returnValue.cType} (*f)($argumentss)) {
+      $argumentAllocations
+
+      $assignValues
+
+      std::cout << \"Calling Test$cName(\" ${arguments.coutExpression()} << \")\\n\";
+
+      ${returnValue.cType} result = f($argumentNames);
+
+      ${returnValue.coutStatement("result")}
+
+      $expects
+
+      // Pass argument that will make the Dart callback throw.
+      ${arguments.firstArgumentName()} = $throwExceptionValue;
+
+      result = f($argumentNames);
+
+      $expectsZero
+
+      // Pass argument that will make the Dart callback return null.
+      ${arguments.firstArgumentName()} = $returnNullValue;
+
+      result = f($argumentNames);
+
+      $expectsZero
+
+      return 0;
+    }
+
+    """;
+  }
+}
+
+/// Some value between 0 and 127 (works in every native type).
+const throwExceptionValue = 42;
+
+/// Some value between 0 and 127 (works in every native type).
+const returnNullValue = 84;
+
+const headerDartCallTest = """
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=5
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'dylib_utils.dart';
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+""";
+
+void writeDartCallTest() {
+  for (bool nnbd in [true, false]) {
+    final StringBuffer buffer = StringBuffer();
+    buffer.write(headerDartCallTest);
+
+    buffer.write("""
+    void main() {
+      for (int i = 0; i < 10; ++i) {
+        ${functions.map((e) => "${e.dartTestName}();").join("\n")}
+      }
+    }
+    """);
+    buffer.writeAll(structs.map((e) => e.dartClass(nnbd)));
+    buffer.writeAll(functions.map((e) => e.dartCallCode));
+
+    final path = callTestPath(nnbd);
+    File(path).writeAsStringSync(buffer.toString());
+    Process.runSync("dartfmt", ["-w", path]);
+  }
+}
+
+String callTestPath(bool nnbd) {
+  final folder = nnbd ? "ffi" : "ffi_2";
+  return Platform.script
+      .resolve("../../$folder/function_structs_by_value_generated_test.dart")
+      .path;
+}
+
+const headerDartCallbackTest = """
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=
+// VMOptions=--deterministic --optimization-counter-threshold=10
+// VMOptions=--use-slow-path
+// VMOptions=--use-slow-path --stacktrace-every=100
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+import "package:ffi/ffi.dart";
+
+import 'callback_tests_utils.dart';
+
+// Reuse the struct classes.
+import 'function_structs_by_value_generated_test.dart';
+
+
+void main() {
+  testCases.forEach((t) {
+    print("==== Running " + t.name);
+    t.run();
+  });
+}
+
+
+""";
+
+void writeDartCallbackTest() {
+  for (bool nnbd in [true, false]) {
+    final StringBuffer buffer = StringBuffer();
+    buffer.write(headerDartCallbackTest);
+
+    buffer.write("""
+  final testCases = [
+    ${functions.map((e) => e.dartCallbackTestConstructor).join("\n")}
+  ];
+  """);
+
+    buffer.writeAll(functions.map((e) => e.dartCallbackCode(nnbd)));
+
+    final path = callbackTestPath(nnbd);
+    File(path).writeAsStringSync(buffer.toString());
+    Process.runSync("dartfmt", ["-w", path]);
+  }
+}
+
+String callbackTestPath(bool nnbd) {
+  final folder = nnbd ? "ffi" : "ffi_2";
+  return Platform.script
+      .resolve(
+          "../../$folder/function_callbacks_structs_by_value_generated_test.dart")
+      .path;
+}
+
+const headerC = """
+// Copyright (c) 2020, 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.
+//
+// This file has been automatically generated. Please do not edit it manually.
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+#if defined(_WIN32)
+#define DART_EXPORT extern "C" __declspec(dllexport)
+#else
+#define DART_EXPORT                                                            \\
+  extern "C" __attribute__((visibility("default"))) __attribute((used))
+#endif
+
+namespace dart {
+
+#define CHECK(X)                                                               \\
+  if (!(X)) {                                                                  \\
+    fprintf(stderr, "%s\\n", "Check failed: " #X);                              \\
+    return 1;                                                                  \\
+  }
+
+#define CHECK_EQ(X, Y) CHECK((X) == (Y))
+
+// Works for positive, negative and zero.
+#define CHECK_APPROX(EXPECTED, ACTUAL)                                         \\
+  CHECK(((EXPECTED * 0.99) <= (ACTUAL) && (EXPECTED * 1.01) >= (ACTUAL)) ||    \\
+        ((EXPECTED * 0.99) >= (ACTUAL) && (EXPECTED * 1.01) <= (ACTUAL)))
+
+""";
+
+const footerC = """
+
+}  // namespace dart
+""";
+
+void writeC() {
+  final StringBuffer buffer = StringBuffer();
+  buffer.write(headerC);
+
+  buffer.writeAll(structs.map((e) => e.cDefinition));
+  buffer.writeAll(functions.map((e) => e.cCallCode));
+  buffer.writeAll(functions.map((e) => e.cCallbackCode));
+
+  buffer.write(footerC);
+
+  File(ccPath).writeAsStringSync(buffer.toString());
+  Process.runSync("clang-format", ["-i", ccPath]);
+}
+
+final ccPath = Platform.script
+    .resolve("../../../runtime/bin/ffi_test/ffi_test_functions_generated.cc")
+    .path;
+
+void printUsage() {
+  print("""
+Generates structs by value tests.
+
+Generates:
+- $ccPath
+- ${callbackTestPath(true)}
+- ${callTestPath(true)}
+- ${callbackTestPath(false)}
+- ${callTestPath(false)}
+""");
+}
+
+void main(List<String> arguments) {
+  if (arguments.length != 0) {
+    printUsage();
+    return;
+  }
+
+  writeDartCallTest();
+  writeDartCallbackTest();
+  writeC();
+}
diff --git a/tests/ffi_2/generator/utils.dart b/tests/ffi_2/generator/utils.dart
new file mode 100644
index 0000000..735e769
--- /dev/null
+++ b/tests/ffi_2/generator/utils.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2020, 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.
+
+extension TestGeneratorStringExtension on String {
+  String upperCaseFirst() => "${this[0].toUpperCase()}${this.substring(1)}";
+
+  String lowerCaseFirst() => "${this[0].toLowerCase()}${this.substring(1)}";
+
+  String makeCComment() => "// " + split("\n").join("\n// ");
+
+  String makeDartDocComment() => "/// " + split("\n").join("\n/// ");
+
+  String limitTo(int lenght) {
+    if (this.length > lenght) {
+      return substring(0, lenght);
+    }
+    return this;
+  }
+
+  String trimCouts() => replaceAll('" << "', '').replaceAll('"<< "', '');
+}
diff --git a/tools/VERSION b/tools/VERSION
index 9b98b0f..94efa75 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 260
+PRERELEASE 261
 PRERELEASE_PATCH 0
\ No newline at end of file