[modular_aot] dart:ffi::_abi recognized method

Issue: https://github.com/dart-lang/sdk/issues/61635
Change-Id: I6d39082849944483395f20db0c47b6d77787d1f9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/568800
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/native_compiler/lib/compilation_set.dart b/pkg/native_compiler/lib/compilation_set.dart
index f2aadda..792660f 100644
--- a/pkg/native_compiler/lib/compilation_set.dart
+++ b/pkg/native_compiler/lib/compilation_set.dart
@@ -29,6 +29,8 @@
   late final RecognizedMethods recognizedMethods = VmRecognizedMethods(
     functionRegistry,
     config.objectLayout,
+    config.targetCPU,
+    config.targetOS,
   );
   late final SnapshotSerializer _snapshot;
   late final StubFactory _stubFactory;
diff --git a/pkg/native_compiler/lib/configuration.dart b/pkg/native_compiler/lib/configuration.dart
index c251a65..a7d640d 100644
--- a/pkg/native_compiler/lib/configuration.dart
+++ b/pkg/native_compiler/lib/configuration.dart
@@ -41,6 +41,15 @@
   static TargetCPU fromName(String name) => values.byName(name);
 }
 
+enum TargetOS {
+  macos,
+  ios;
+
+  static final String defaultName = macos.name;
+  static final List<String> allowedNames = [for (final v in values) v.name];
+  static TargetOS fromName(String name) => values.byName(name);
+}
+
 enum ImageFormat {
   macho;
 
@@ -51,6 +60,7 @@
 
 abstract base class Configuration(
   final TargetCPU targetCPU,
+  final TargetOS targetOS,
   final ImageFormat imageFormat, {
   required final bool enableAsserts,
   required final bool compilePlatform,
@@ -121,6 +131,7 @@
 final class DevelopmentCompilerConfiguration extends Configuration {
   DevelopmentCompilerConfiguration(
     super.targetCPU,
+    super.targetOS,
     super.imageFormat, {
     required super.enableAsserts,
     required super.compilePlatform,
diff --git a/pkg/native_compiler/lib/front_end/recognized_methods.dart b/pkg/native_compiler/lib/front_end/recognized_methods.dart
index 02e88ac..f594178 100644
--- a/pkg/native_compiler/lib/front_end/recognized_methods.dart
+++ b/pkg/native_compiler/lib/front_end/recognized_methods.dart
@@ -12,10 +12,12 @@
 import 'package:cfg/ir/types.dart';
 import 'package:kernel/ast.dart' as ast;
 import 'package:kernel/external_name.dart' show getExternalName;
+import 'package:native_compiler/configuration.dart';
 import 'package:native_compiler/runtime/constant_objects.dart';
 import 'package:native_compiler/runtime/object_layout.dart';
 import 'package:native_compiler/runtime/vm_defs.dart';
 import 'package:vm/modular/transformations/pragma.dart';
+import 'package:vm/modular/transformations/ffi/abi.dart' as ffi_abi;
 
 /// Build IR for native methods.
 void buildNativeMethod(
@@ -680,6 +682,8 @@
 final class VmRecognizedMethods(
   final FunctionRegistry functionRegistry,
   final ObjectLayout objectLayout,
+  final TargetCPU targetCPU,
+  final TargetOS targetOS,
 ) extends CommonRecognizedMethods {
   final coreTypes = GlobalContext.instance.coreTypes;
 
@@ -1761,6 +1765,17 @@
       buildExtensionStreamHasListener(builder, objectLayout);
     },
 
+    // dart:ffi
+    index.getTopLevelProcedure('dart:ffi', '_abi'): (FlowGraphBuilder builder) {
+      final targetAbi = switch ((targetOS, targetCPU)) {
+        (.macos, .arm64) => ffi_abi.Abi.macosArm64,
+        (.ios, .arm64) => ffi_abi.Abi.iosArm64,
+      };
+      final targetAbiIndex = ffi_abi.Abi.values.indexOf(targetAbi);
+      assert(targetAbiIndex >= 0);
+      buildConstantGetter(builder, ConstantValue.fromInt(targetAbiIndex));
+    },
+
     // dart:_vm
     index.getProcedure(
       'dart:_vm',
diff --git a/pkg/native_compiler/lib/modular_aot_compiler.dart b/pkg/native_compiler/lib/modular_aot_compiler.dart
index a860715..b52b26c 100644
--- a/pkg/native_compiler/lib/modular_aot_compiler.dart
+++ b/pkg/native_compiler/lib/modular_aot_compiler.dart
@@ -87,6 +87,12 @@
     defaultsTo: TargetCPU.defaultName,
   )
   ..addOption(
+    'target-os',
+    help: 'Target operating system.',
+    allowed: TargetOS.allowedNames,
+    defaultsTo: TargetOS.defaultName,
+  )
+  ..addOption(
     'image-format',
     help: 'Image format of the output snapshot.',
     allowed: ImageFormat.allowedNames,
@@ -221,6 +227,7 @@
   final bool trackCreationLocations = options['track-creation-locations'];
 
   final TargetCPU targetCPU = TargetCPU.fromName(options['target-arch']);
+  final TargetOS targetOS = TargetOS.fromName(options['target-os']);
   final ImageFormat imageFormat = ImageFormat.fromName(options['image-format']);
 
   final String? printFlowGraph = options['print-flow-graph'];
@@ -330,6 +337,7 @@
   final coreLibraries = LibraryIndex.coreLibraries(component);
   final config = DevelopmentCompilerConfiguration(
     targetCPU,
+    targetOS,
     imageFormat,
     enableAsserts: enableAsserts,
     compilePlatform: compilePlatform,
diff --git a/pkg/native_compiler/test/ir_test.dart b/pkg/native_compiler/test/ir_test.dart
index d8c9600..54861b5 100644
--- a/pkg/native_compiler/test/ir_test.dart
+++ b/pkg/native_compiler/test/ir_test.dart
@@ -33,6 +33,7 @@
 import 'package:native_compiler/back_end/back_end_state.dart';
 import 'package:native_compiler/back_end/regalloc_checker.dart';
 import 'package:native_compiler/back_end/register_allocator.dart';
+import 'package:native_compiler/configuration.dart';
 import 'package:native_compiler/front_end/recognized_methods.dart';
 import 'package:native_compiler/passes/lowering.dart';
 import 'package:native_compiler/passes/reorder_blocks.dart';
@@ -120,6 +121,8 @@
   late final RecognizedMethods recognizedMethods = VmRecognizedMethods(
     functionRegistry,
     objectLayout,
+    TargetCPU.arm64,
+    TargetOS.macos,
   );
 
   @override