// Copyright (c) 2022, 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:dart2wasm/class_info.dart';
import 'package:dart2wasm/code_generator.dart';
import 'package:dart2wasm/dynamic_forwarders.dart';
import 'package:dart2wasm/translator.dart';

import 'package:kernel/ast.dart';

import 'package:wasm_builder/wasm_builder.dart' as w;
import 'abi.dart' show kWasmAbiEnumIndex;

typedef CodeGenCallback = void Function(CodeGenerator);

/// Specialized code generation for external members.
///
/// The code is generated either inlined at the call site, or as the body of
/// the member in [generateMemberIntrinsic].
class Intrinsifier {
  final CodeGenerator codeGen;

  static const w.ValueType boolType = w.NumType.i32;
  static const w.ValueType intType = w.NumType.i64;
  static const w.ValueType doubleType = w.NumType.f64;

  static final Map<w.ValueType, Map<w.ValueType, Map<String, CodeGenCallback>>>
      _binaryOperatorMap = {
    boolType: {
      boolType: {
        '|': (c) => c.b.i32_or(),
        '^': (c) => c.b.i32_xor(),
        '&': (c) => c.b.i32_and(),
      }
    },
    intType: {
      intType: {
        '+': (c) => c.b.i64_add(),
        '-': (c) => c.b.i64_sub(),
        '*': (c) => c.b.i64_mul(),
        '&': (c) => c.b.i64_and(),
        '|': (c) => c.b.i64_or(),
        '^': (c) => c.b.i64_xor(),
        '<': (c) => c.b.i64_lt_s(),
        '<=': (c) => c.b.i64_le_s(),
        '>': (c) => c.b.i64_gt_s(),
        '>=': (c) => c.b.i64_ge_s(),
        '_div_s': (c) => c.b.i64_div_s(),
        '_shl': (c) => c.b.i64_shl(),
        '_shr_s': (c) => c.b.i64_shr_s(),
        '_shr_u': (c) => c.b.i64_shr_u(),
        '_le_u': (c) => c.b.i64_le_u(),
        '_lt_u': (c) => c.b.i64_lt_u(),
        '~/': (c) => c.call(c.translator.truncDiv.reference),
      }
    },
    doubleType: {
      doubleType: {
        '+': (c) => c.b.f64_add(),
        '-': (c) => c.b.f64_sub(),
        '*': (c) => c.b.f64_mul(),
        '/': (c) => c.b.f64_div(),
        '<': (c) => c.b.f64_lt(),
        '<=': (c) => c.b.f64_le(),
        '>': (c) => c.b.f64_gt(),
        '>=': (c) => c.b.f64_ge(),
        '_copysign': (c) => c.b.f64_copysign(),
      }
    },
  };

  static final Map<w.ValueType, Map<String, CodeGenCallback>>
      _unaryOperatorMap = {
    intType: {
      'unary-': (c) {
        c.b.i64_const(-1);
        c.b.i64_mul();
      },
      '~': (c) {
        c.b.i64_const(-1);
        c.b.i64_xor();
      },
      'toDouble': (c) {
        c.b.f64_convert_i64_s();
      },
    },
    doubleType: {
      'unary-': (c) {
        c.b.f64_neg();
      },
      'floorToDouble': (c) {
        c.b.f64_floor();
      },
      'ceilToDouble': (c) {
        c.b.f64_ceil();
      },
      'truncateToDouble': (c) {
        c.b.f64_trunc();
      },
      '_toInt': (c) {
        c.b.i64_trunc_sat_f64_s();
      },
    },
  };

  static final Map<String, w.ValueType> _unaryResultMap = {
    'toDouble': w.NumType.f64,
    'floorToDouble': w.NumType.f64,
    'ceilToDouble': w.NumType.f64,
    'truncateToDouble': w.NumType.f64,
    '_toInt': w.NumType.i64,
  };

  Translator get translator => codeGen.translator;
  w.InstructionsBuilder get b => codeGen.b;

  DartType dartTypeOf(Expression exp) => codeGen.dartTypeOf(exp);

  w.ValueType typeOfExp(Expression exp) {
    return translator.translateType(dartTypeOf(exp));
  }

  static bool isComparison(String op) =>
      op == '<' ||
      op == '<=' ||
      op == '>' ||
      op == '>=' ||
      op == '_le_u' ||
      op == '_lt_u';

  Intrinsifier(this.codeGen);

  /// Generate inline code for an [InstanceGet] if the member is an inlined
  /// intrinsic.
  w.ValueType? generateInstanceGetterIntrinsic(InstanceGet node) {
    Expression receiver = node.receiver;
    String name = node.name.text;
    Member target = node.interfaceTarget;
    Class cls = target.enclosingClass!;

    // WasmAnyRef.isObject
    if (cls == translator.wasmAnyRefClass) {
      assert(name == "isObject");
      codeGen.wrap(receiver, w.RefType.any(nullable: false));
      b.ref_test(translator.topInfo.nonNullableType);
      return w.NumType.i32;
    }

    // WasmArrayRef.length
    if (cls == translator.wasmArrayRefClass) {
      assert(name == 'length');
      codeGen.wrap(receiver, w.RefType.array(nullable: false));
      b.array_len();
      b.i64_extend_i32_u();
      return w.NumType.i64;
    }

    // WasmTable.size
    if (cls == translator.wasmTableClass) {
      if (receiver is! StaticGet || receiver.target is! Field) {
        throw "Table size not directly on a static field"
            " at ${node.location}";
      }
      w.Table table = translator.getTable(receiver.target as Field)!;
      assert(name == "size");
      b.table_size(table);
      return w.NumType.i32;
    }

    // int.bitlength
    if (cls == translator.coreTypes.intClass && name == 'bitLength') {
      w.Local temp = codeGen.function.addLocal(w.NumType.i64);
      b.i64_const(64);
      codeGen.wrap(receiver, w.NumType.i64);
      b.local_tee(temp);
      b.local_get(temp);
      b.i64_const(63);
      b.i64_shr_s();
      b.i64_xor();
      b.i64_clz();
      b.i64_sub();
      return w.NumType.i64;
    }

    // _Compound._typedDataBase
    if (cls == translator.ffiCompoundClass && name == '_typedDataBase') {
      // A compound (subclass of Struct or Union) is represented by its i32
      // address. The _typedDataBase field contains a Pointer pointing to the
      // compound, whose representation is the same.
      codeGen.wrap(receiver, w.NumType.i32);
      return w.NumType.i32;
    }

    // Pointer.address
    if (cls == translator.ffiPointerClass && name == 'address') {
      // A Pointer is represented by its i32 address.
      codeGen.wrap(receiver, w.NumType.i32);
      b.i64_extend_i32_u();
      return w.NumType.i64;
    }

    return null;
  }

  /// Generate inline code for an [InstanceInvocation] if the member is an
  /// inlined intrinsic.
  w.ValueType? generateInstanceIntrinsic(InstanceInvocation node) {
    Expression receiver = node.receiver;
    DartType receiverType = dartTypeOf(receiver);
    String name = node.name.text;
    Procedure target = node.interfaceTarget;
    Class cls = target.enclosingClass!;

    // WasmAnyRef.toObject
    if (cls == translator.wasmAnyRefClass && name == "toObject") {
      w.Label succeed = b.block(const [], [translator.topInfo.nonNullableType]);
      codeGen.wrap(receiver, const w.RefType.any(nullable: false));
      b.br_on_cast(succeed, const w.RefType.any(nullable: false),
          translator.topInfo.nonNullableType);
      codeGen.throwWasmRefError("a Dart object");
      b.end(); // succeed
      return translator.topInfo.nonNullableType;
    }

    // Wasm(I32|I64|F32|F64) conversions
    if (cls.superclass == translator.wasmTypesBaseClass) {
      w.StorageType? receiverType = translator.builtinTypes[cls];
      switch (receiverType) {
        case w.NumType.i32:
          codeGen.wrap(receiver, w.NumType.i32);
          switch (name) {
            case "toIntSigned":
              b.i64_extend_i32_s();
              return w.NumType.i64;
            case "toIntUnsigned":
              b.i64_extend_i32_u();
              return w.NumType.i64;
            case "toBool":
              b.i32_const(0);
              b.i32_ne();
              return w.NumType.i32;
            default:
              throw 'Unknown WasmI32 member $name';
          }
        case w.NumType.i64:
          switch (name) {
            case "toInt":
              codeGen.wrap(receiver, w.NumType.i64);
              return w.NumType.i64;
            case "leU":
              codeGen.wrap(receiver, w.NumType.i64);
              codeGen.wrap(node.arguments.positional[0], w.NumType.i64);
              b.i64_le_u();
              return boolType;
            case "ltU":
              codeGen.wrap(receiver, w.NumType.i64);
              codeGen.wrap(node.arguments.positional[0], w.NumType.i64);
              b.i64_lt_u();
              return boolType;
            default:
              throw 'Unknown WasmI64 member $name';
          }
        case w.NumType.f32:
          assert(name == "toDouble");
          codeGen.wrap(receiver, w.NumType.f32);
          b.f64_promote_f32();
          return w.NumType.f64;
        case w.NumType.f64:
          switch (name) {
            case "toDouble":
              codeGen.wrap(receiver, w.NumType.f64);
              return w.NumType.f64;
            case "truncSatS":
              codeGen.wrap(receiver, w.NumType.f64);
              b.i64_trunc_sat_f64_s();
              return w.NumType.i64;
            default:
              throw 'Unknown WasmF64 member $name';
          }
      }
    }

    // WasmTable.[] and WasmTable.[]=
    if (cls == translator.wasmTableClass) {
      if (receiver is! StaticGet || receiver.target is! Field) {
        throw "Table indexing not directly on a static field"
            " at ${node.location}";
      }
      w.Table table = translator.getTable(receiver.target as Field)!;
      codeGen.wrap(node.arguments.positional[0], w.NumType.i32);
      if (name == '[]') {
        b.table_get(table);
        return table.type;
      } else {
        assert(name == '[]=');
        codeGen.wrap(node.arguments.positional[1], table.type);
        b.table_set(table);
        return codeGen.voidMarker;
      }
    }

    // List.[] on list constants
    if (receiver is ConstantExpression &&
        receiver.constant is ListConstant &&
        name == '[]') {
      Expression arg = node.arguments.positional.single;

      // If the list is indexed by a constant, or the ABI index, just pick
      // the element at that constant index.
      int? constIndex = null;
      if (arg is IntLiteral) {
        constIndex = arg.value;
      } else if (arg is ConstantExpression) {
        Constant argConst = arg.constant;
        if (argConst is IntConstant) {
          constIndex = argConst.value;
        }
      } else if (arg is StaticInvocation) {
        if (arg.target.enclosingLibrary.name == "dart.ffi" &&
            arg.name.text == "_abi") {
          constIndex = kWasmAbiEnumIndex;
        }
      }
      if (constIndex != null) {
        ListConstant list = receiver.constant as ListConstant;
        Expression element = ConstantExpression(list.entries[constIndex]);
        return codeGen.wrap(element, typeOfExp(element));
      }

      return null;
    }

    if (node.arguments.positional.length == 1) {
      // Binary operator
      Expression left = node.receiver;
      Expression right = node.arguments.positional.single;
      DartType argType = dartTypeOf(right);
      w.ValueType leftType = translator.translateType(receiverType);
      w.ValueType rightType = translator.translateType(argType);
      var code = _binaryOperatorMap[leftType]?[rightType]?[name];
      if (code != null) {
        w.ValueType outType = isComparison(name) ? w.NumType.i32 : leftType;
        codeGen.wrap(left, leftType);
        codeGen.wrap(right, rightType);
        code(codeGen);
        return outType;
      }
    } else if (node.arguments.positional.isEmpty) {
      // Unary operator
      Expression operand = node.receiver;
      w.ValueType opType = translator.translateType(receiverType);
      var code = _unaryOperatorMap[opType]?[name];
      if (code != null) {
        codeGen.wrap(operand, opType);
        code(codeGen);
        return _unaryResultMap[name] ?? opType;
      }
    }

    return null;
  }

  /// Generate inline code for an [EqualsCall] with an unboxed receiver.
  w.ValueType? generateEqualsIntrinsic(EqualsCall node) {
    w.ValueType leftType = typeOfExp(node.left);
    w.ValueType rightType = typeOfExp(node.right);

    // Compare bool, Pointer or WasmI32.
    if (leftType == w.NumType.i32 && rightType == w.NumType.i32) {
      codeGen.wrap(node.left, w.NumType.i32);
      codeGen.wrap(node.right, w.NumType.i32);
      b.i32_eq();
      return w.NumType.i32;
    }

    // Compare int or WasmI64.
    if (leftType == w.NumType.i64 && rightType == w.NumType.i64) {
      codeGen.wrap(node.left, w.NumType.i64);
      codeGen.wrap(node.right, w.NumType.i64);
      b.i64_eq();
      return w.NumType.i32;
    }

    // Compare WasmF32.
    if (leftType == w.NumType.f32 && rightType == w.NumType.f32) {
      codeGen.wrap(node.left, w.NumType.f32);
      codeGen.wrap(node.right, w.NumType.f32);
      b.f32_eq();
      return w.NumType.i32;
    }

    // Compare double or WasmF64.
    if (leftType == doubleType && rightType == doubleType) {
      codeGen.wrap(node.left, w.NumType.f64);
      codeGen.wrap(node.right, w.NumType.f64);
      b.f64_eq();
      return w.NumType.i32;
    }

    return null;
  }

  /// Generate inline code for a [StaticGet] if the member is an inlined
  /// intrinsic.
  w.ValueType? generateStaticGetterIntrinsic(StaticGet node) {
    final Member target = node.target;
    final Class? cls = target.enclosingClass;

    // ClassID getters
    if (cls?.name == 'ClassID') {
      final libAndClassName = translator.getPragma(target, "wasm:class-id");
      if (libAndClassName != null) {
        List<String> libAndClassNameParts = libAndClassName.split("#");
        final String lib = libAndClassNameParts[0];
        final String className = libAndClassNameParts[1];
        Class cls = translator.libraries
            .firstWhere((l) => l.name == lib && l.importUri.scheme == 'dart',
                orElse: () =>
                    throw 'Library $lib not found (${target.location})')
            .classes
            .firstWhere((c) => c.name == className,
                orElse: () =>
                    throw 'Class $className not found in library $lib '
                        '(${target.location})');
        int classId = translator.classInfo[cls]!.classId;
        b.i64_const(classId);
        return w.NumType.i64;
      }

      if (target.name.text == 'firstNonMasqueradedInterfaceClassCid') {
        b.i64_const(
            translator.classIdNumbering.firstNonMasqueradedInterfaceClassCid);
        return w.NumType.i64;
      }
    }

    // nullptr
    if (target.enclosingLibrary.name == "dart.ffi" &&
        target.name.text == "nullptr") {
      // A Pointer is represented by its i32 address.
      b.i32_const(0);
      return w.NumType.i32;
    }

    if (target.enclosingLibrary.name == "dart.core") {
      if (target.name.text == "_isIntrinsified") {
        // This is part of the VM's [BigInt] implementation. We just return false.
        // TODO(joshualitt): Can we find another way to reuse this patch file
        // without hardcoding this case?
        b.i32_const(0);
        return w.NumType.i32;
      }
    }

    return null;
  }

  /// Generate inline code for a [StaticInvocation] if the member is an inlined
  /// intrinsic.
  w.ValueType? generateStaticIntrinsic(StaticInvocation node) {
    String name = node.name.text;
    final Procedure target = node.target;
    final Library library = target.enclosingLibrary;
    Class? cls = target.enclosingClass;

    if (target.isExtensionMember && library == translator.wasmLibrary) {
      final (ext, extDescriptor) = translator.extensionOfMember(target);
      final memberName = extDescriptor.name.text;

      // extension WasmArrayExt on WasmArray<T>
      if (ext.name == 'WasmArrayExt') {
        final dartWasmArrayType = dartTypeOf(node.arguments.positional.first);
        final dartElementType =
            (dartWasmArrayType as InterfaceType).typeArguments.single;
        w.ArrayType arrayType =
            translator.arrayTypeForDartType(dartElementType);
        w.StorageType wasmType = arrayType.elementType.type;

        switch (memberName) {
          case '[]':
            final array = node.arguments.positional[0];
            final index = node.arguments.positional[1];
            codeGen.wrap(array, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(index, w.NumType.i64);
            b.i32_wrap_i64();
            if (wasmType is w.PackedType) {
              b.array_get_u(arrayType);
            } else {
              b.array_get(arrayType);
            }
            return wasmType.unpacked;
          case '[]=':
            final array = node.arguments.positional[0];
            final index = node.arguments.positional[1];
            final value = node.arguments.positional[2];
            codeGen.wrap(array, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(index, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.wrap(value, typeOfExp(value));
            b.array_set(arrayType);
            return codeGen.voidMarker;
          case 'copy':
            final destArray = node.arguments.positional[0];
            final destOffset = node.arguments.positional[1];
            final sourceArray = node.arguments.positional[2];
            final sourceOffset = node.arguments.positional[3];
            final size = node.arguments.positional[4];

            codeGen.wrap(destArray, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(destOffset, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.wrap(
                sourceArray, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(sourceOffset, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.wrap(size, w.NumType.i64);
            b.i32_wrap_i64();
            b.array_copy(arrayType, arrayType);
            return codeGen.voidMarker;
          case 'fill':
            final array = node.arguments.positional[0];
            final offset = node.arguments.positional[1];
            final value = node.arguments.positional[2];
            final size = node.arguments.positional[3];

            codeGen.wrap(array, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(offset, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.wrap(value, translator.translateType(dartElementType));
            codeGen.wrap(size, w.NumType.i64);
            b.i32_wrap_i64();
            b.array_fill(arrayType);
            return codeGen.voidMarker;
          default:
            throw 'unknown';
        }
      }

      // extension (I8|I16|I32|I64|F32|F64)ArrayExt on WasmArray<...>
      if (ext.name.endsWith('ArrayExt')) {
        final dartWasmArrayType = dartTypeOf(node.arguments.positional.first);
        final dartElementType =
            (dartWasmArrayType as InterfaceType).typeArguments.single;
        w.ArrayType arrayType =
            translator.arrayTypeForDartType(dartElementType);
        w.StorageType wasmType = arrayType.elementType.type;

        final innerExtend =
            wasmType == w.PackedType.i8 || wasmType == w.PackedType.i16;
        final outerExtend =
            wasmType.unpacked == w.NumType.i32 || wasmType == w.NumType.f32;

        // WasmArray<I*>.(readSigned|readUnsigned|write)
        // WasmArray<F*>.(read|write)
        switch (memberName) {
          case 'read':
          case 'readSigned':
          case 'readUnsigned':
            final unsigned = memberName == 'readUnsigned';
            final array = node.arguments.positional[0];
            final index = node.arguments.positional[1];
            codeGen.wrap(array, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(index, w.NumType.i64);
            b.i32_wrap_i64();
            if (innerExtend) {
              if (unsigned) {
                b.array_get_u(arrayType);
              } else {
                b.array_get_s(arrayType);
              }
            } else {
              b.array_get(arrayType);
            }
            if (outerExtend) {
              if (wasmType == w.NumType.f32) {
                b.f64_promote_f32();
                return w.NumType.f64;
              } else {
                if (unsigned) {
                  b.i64_extend_i32_u();
                } else {
                  b.i64_extend_i32_s();
                }
                return w.NumType.i64;
              }
            }
            return wasmType.unpacked;
          case 'write':
            final array = node.arguments.positional[0];
            final index = node.arguments.positional[1];
            final value = node.arguments.positional[2];
            codeGen.wrap(array, w.RefType.def(arrayType, nullable: false));
            codeGen.wrap(index, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.wrap(value, typeOfExp(value));
            if (outerExtend) {
              if (wasmType == w.NumType.f32) {
                b.f32_demote_f64();
              } else {
                b.i32_wrap_i64();
              }
            }
            b.array_set(arrayType);
            return codeGen.voidMarker;
        }
      }
    }

    // dart:core static functions
    if (node.target.enclosingLibrary == translator.coreTypes.coreLibrary) {
      switch (name) {
        case "identical":
          Expression first = node.arguments.positional[0];
          Expression second = node.arguments.positional[1];
          DartType boolType = translator.coreTypes.boolNonNullableRawType;
          InterfaceType intType = translator.coreTypes.intNonNullableRawType;
          DartType doubleType = translator.coreTypes.doubleNonNullableRawType;
          List<DartType> types = [dartTypeOf(first), dartTypeOf(second)];
          if (types.every((t) => t == intType)) {
            codeGen.wrap(first, w.NumType.i64);
            codeGen.wrap(second, w.NumType.i64);
            b.i64_eq();
            return w.NumType.i32;
          }
          if (types.any((t) =>
              t is InterfaceType &&
              t != boolType &&
              t != doubleType &&
              !translator.hierarchy
                  .isSubInterfaceOf(intType.classNode, t.classNode))) {
            codeGen.wrap(first, w.RefType.eq(nullable: true));
            codeGen.wrap(second, w.RefType.eq(nullable: true));
            b.ref_eq();
            return w.NumType.i32;
          }
          break;
        case "_getTypeRulesSupers":
          return translator.types.makeTypeRulesSupers(b);
        case "_getTypeRulesSubstitutions":
          return translator.types.makeTypeRulesSubstitutions(b);
        case "_getTypeNames":
          return translator.types.makeTypeNames(b);
        case "_isObjectClassId":
          final classId = node.arguments.positional.single;

          final objectClassId = translator
              .classIdNumbering.classIds[translator.coreTypes.objectClass]!;

          codeGen.wrap(classId, w.NumType.i64);
          b.i32_wrap_i64();
          b.emitClassIdRangeCheck(
              codeGen, [Range(objectClassId, objectClassId)]);
          return w.NumType.i32;
        case "_isClosureClassId":
          final classId = node.arguments.positional.single;

          final ranges = translator.classIdNumbering
              .getConcreteClassIdRanges(translator.coreTypes.functionClass);
          assert(ranges.length <= 1);

          codeGen.wrap(classId, w.NumType.i64);
          b.i32_wrap_i64();
          b.emitClassIdRangeCheck(codeGen, ranges);
          return w.NumType.i32;
        case "_isRecordClassId":
          final classId = node.arguments.positional.single;

          final ranges = translator.classIdNumbering
              .getConcreteClassIdRanges(translator.coreTypes.recordClass);
          assert(ranges.length <= 1);

          codeGen.wrap(classId, w.NumType.i64);
          b.i32_wrap_i64();
          b.emitClassIdRangeCheck(codeGen, ranges);
          return w.NumType.i32;
      }
    }

    // dart:_object_helper static functions.
    if (node.target.enclosingLibrary.name == 'dart._object_helper') {
      switch (name) {
        case "getHash":
          Expression arg = node.arguments.positional[0];
          w.ValueType objectType = translator.objectInfo.nonNullableType;
          codeGen.wrap(arg, objectType);
          b.struct_get(translator.objectInfo.struct, FieldIndex.identityHash);
          b.i64_extend_i32_u();
          return w.NumType.i64;
        case "setHash":
          Expression arg = node.arguments.positional[0];
          Expression hash = node.arguments.positional[1];
          w.ValueType objectType = translator.objectInfo.nonNullableType;
          codeGen.wrap(arg, objectType);
          codeGen.wrap(hash, w.NumType.i64);
          b.i32_wrap_i64();
          b.struct_set(translator.objectInfo.struct, FieldIndex.identityHash);
          return codeGen.voidMarker;
      }
    }

    // dart:_internal static functions
    if (node.target.enclosingLibrary.name == "dart._internal") {
      switch (name) {
        case "unsafeCast":
        case "unsafeCastOpaque":
          Expression operand = node.arguments.positional.single;
          // Just evaluate the operand and let the context convert it to the
          // expected type.
          return codeGen.wrap(operand, typeOfExp(operand));
        case "_nativeEffect":
          // Ignore argument
          return translator.voidMarker;
        case "floatToIntBits":
          codeGen.wrap(node.arguments.positional.single, w.NumType.f64);
          b.f32_demote_f64();
          b.i32_reinterpret_f32();
          b.i64_extend_i32_u();
          return w.NumType.i64;
        case "intBitsToFloat":
          codeGen.wrap(node.arguments.positional.single, w.NumType.i64);
          b.i32_wrap_i64();
          b.f32_reinterpret_i32();
          b.f64_promote_f32();
          return w.NumType.f64;
        case "doubleToIntBits":
          codeGen.wrap(node.arguments.positional.single, w.NumType.f64);
          b.i64_reinterpret_f64();
          return w.NumType.i64;
        case "intBitsToDouble":
          codeGen.wrap(node.arguments.positional.single, w.NumType.i64);
          b.f64_reinterpret_i64();
          return w.NumType.f64;
        case "getID":
          ClassInfo info = translator.topInfo;
          codeGen.wrap(node.arguments.positional.single, info.nonNullableType);
          b.struct_get(info.struct, FieldIndex.classId);
          b.i64_extend_i32_u();
          return w.NumType.i64;
        case "makeListFixedLength":
          return _changeListClassID(node, translator.fixedLengthListClass);
        case "makeFixedListUnmodifiable":
          return _changeListClassID(node, translator.immutableListClass);
      }
    }

    // dart:ffi static functions
    if (node.target.enclosingLibrary.name == "dart.ffi") {
      // Pointer.fromAddress
      if (name == "fromAddress") {
        // A Pointer is represented by its i32 address.
        codeGen.wrap(node.arguments.positional.single, w.NumType.i64);
        b.i32_wrap_i64();
        return w.NumType.i32;
      }

      // Accesses to Pointer.value, Pointer.value=, Pointer.[], Pointer.[]= and
      // the members of structs and unions are desugared by the FFI kernel
      // transformations into calls to memory load and store functions.
      RegExp loadStoreFunctionNames = RegExp("^_(load|store)"
          "((Int|Uint)(8|16|32|64)|(Float|Double)(Unaligned)?|Pointer)\$");
      if (loadStoreFunctionNames.hasMatch(name)) {
        Expression pointerArg = node.arguments.positional[0];
        Expression offsetArg = node.arguments.positional[1];
        codeGen.wrap(pointerArg, w.NumType.i32);
        int offset;
        if (offsetArg is IntLiteral) {
          offset = offsetArg.value;
        } else if (offsetArg is ConstantExpression &&
            offsetArg.constant is IntConstant) {
          offset = (offsetArg.constant as IntConstant).value;
        } else {
          codeGen.wrap(offsetArg, w.NumType.i64);
          b.i32_wrap_i64();
          b.i32_add();
          offset = 0;
        }
        switch (name) {
          case "_loadInt8":
            b.i64_load8_s(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadUint8":
            b.i64_load8_u(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadInt16":
            b.i64_load16_s(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadUint16":
            b.i64_load16_u(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadInt32":
            b.i64_load32_s(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadUint32":
            b.i64_load32_u(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadInt64":
          case "_loadUint64":
            b.i64_load(translator.ffiMemory, offset);
            return w.NumType.i64;
          case "_loadFloat":
            b.f32_load(translator.ffiMemory, offset);
            b.f64_promote_f32();
            return w.NumType.f64;
          case "_loadFloatUnaligned":
            b.f32_load(translator.ffiMemory, offset, 0);
            b.f64_promote_f32();
            return w.NumType.f64;
          case "_loadDouble":
            b.f64_load(translator.ffiMemory, offset);
            return w.NumType.f64;
          case "_loadDoubleUnaligned":
            b.f64_load(translator.ffiMemory, offset, 0);
            return w.NumType.f64;
          case "_loadPointer":
            b.i32_load(translator.ffiMemory, offset);
            return w.NumType.i32;
          case "_storeInt8":
          case "_storeUint8":
            codeGen.wrap(node.arguments.positional[2], w.NumType.i64);
            b.i64_store8(translator.ffiMemory, offset);
            return translator.voidMarker;
          case "_storeInt16":
          case "_storeUint16":
            codeGen.wrap(node.arguments.positional[2], w.NumType.i64);
            b.i64_store16(translator.ffiMemory, offset);
            return translator.voidMarker;
          case "_storeInt32":
          case "_storeUint32":
            codeGen.wrap(node.arguments.positional[2], w.NumType.i64);
            b.i64_store32(translator.ffiMemory, offset);
            return translator.voidMarker;
          case "_storeInt64":
          case "_storeUint64":
            codeGen.wrap(node.arguments.positional[2], w.NumType.i64);
            b.i64_store(translator.ffiMemory, offset);
            return translator.voidMarker;
          case "_storeFloat":
            codeGen.wrap(node.arguments.positional[2], w.NumType.f64);
            b.f32_demote_f64();
            b.f32_store(translator.ffiMemory, offset);
            return translator.voidMarker;
          case "_storeFloatUnaligned":
            codeGen.wrap(node.arguments.positional[2], w.NumType.f64);
            b.f32_demote_f64();
            b.f32_store(translator.ffiMemory, offset, 0);
            return translator.voidMarker;
          case "_storeDouble":
            codeGen.wrap(node.arguments.positional[2], w.NumType.f64);
            b.f64_store(translator.ffiMemory, offset);
            return translator.voidMarker;
          case "_storeDoubleUnaligned":
            codeGen.wrap(node.arguments.positional[2], w.NumType.f64);
            b.f64_store(translator.ffiMemory, offset, 0);
            return translator.voidMarker;
          case "_storePointer":
            codeGen.wrap(node.arguments.positional[2], w.NumType.i32);
            b.i32_store(translator.ffiMemory, offset);
            return translator.voidMarker;
        }
      }
    }

    if (cls != null && translator.isWasmType(cls)) {
      // WasmArray constructors
      if (cls == translator.wasmArrayClass) {
        final dartElementType = node.arguments.types.single;
        w.ArrayType arrayType =
            translator.arrayTypeForDartType(dartElementType);
        final elementType = arrayType.elementType.type;
        final isDefaultable = elementType is! w.RefType || elementType.nullable;
        if (!isDefaultable && node.arguments.positional.length == 1) {
          throw 'The element type $dartElementType does not have a default value'
              '- please use WasmArray<$dartElementType>.filled() instead.';
        }

        Expression length = node.arguments.positional[0];
        codeGen.wrap(length, w.NumType.i64);
        b.i32_wrap_i64();
        if (node.arguments.positional.length < 2) {
          b.array_new_default(arrayType);
        } else {
          Expression initialValue = node.arguments.positional[1];
          if (initialValue is NullLiteral ||
              initialValue is ConstantExpression &&
                  initialValue.constant is NullConstant) {
            // Initialize to `null`
            b.array_new_default(arrayType);
          } else {
            // Initialize to the provided value
            w.Local lengthTemp = codeGen.addLocal(w.NumType.i32);
            b.local_set(lengthTemp);
            codeGen.wrap(initialValue, arrayType.elementType.type.unpacked);
            b.local_get(lengthTemp);
            b.array_new(arrayType);
          }
        }
        return w.RefType.def(arrayType, nullable: false);
      }

      // (WasmFuncRef|WasmFunction).fromRef constructors
      if (cls == translator.wasmFunctionClass && name == "fromFuncRef") {
        Expression ref = node.arguments.positional[0];
        w.RefType resultType = typeOfExp(node) as w.RefType;
        w.Label succeed = b.block(const [], [resultType]);
        codeGen.wrap(ref, w.RefType.func(nullable: false));
        b.br_on_cast(succeed, w.RefType.func(nullable: false), resultType);
        codeGen.throwWasmRefError("a function with the expected signature");
        b.end(); // succeed
        return resultType;
      }

      // WasmFunction.fromFunction constructor
      if (cls == translator.wasmFunctionClass) {
        assert(name == "fromFunction");
        Expression f = node.arguments.positional[0];
        if (f is! ConstantExpression || f.constant is! StaticTearOffConstant) {
          throw "Argument to WasmFunction.fromFunction isn't a static function";
        }
        StaticTearOffConstant func = f.constant as StaticTearOffConstant;
        w.BaseFunction wasmFunction =
            translator.functions.getFunction(func.targetReference);
        w.Global functionRef = translator.makeFunctionRef(wasmFunction);
        b.global_get(functionRef);
        return functionRef.type.type;
      }

      // Wasm(AnyRef|FuncRef|EqRef|StructRef|I32|I64|F32|F64) constructors
      Expression value = node.arguments.positional[0];
      w.StorageType targetType = translator.builtinTypes[cls]!;
      switch (targetType) {
        case w.NumType.i32:
          switch (name) {
            case "fromInt":
              codeGen.wrap(value, w.NumType.i64);
              b.i32_wrap_i64();
              return w.NumType.i32;
            case "int8FromInt":
              codeGen.wrap(value, w.NumType.i64);
              b.i32_wrap_i64();
              b.i32_extend8_s();
              return w.NumType.i32;
            case "uint8FromInt":
              codeGen.wrap(value, w.NumType.i64);
              b.i32_wrap_i64();
              b.i32_const(0xFF);
              b.i32_and();
              return w.NumType.i32;
            case "int16FromInt":
              codeGen.wrap(value, w.NumType.i64);
              b.i32_wrap_i64();
              b.i32_extend16_s();
              return w.NumType.i32;
            case "uint16FromInt":
              codeGen.wrap(value, w.NumType.i64);
              b.i32_wrap_i64();
              b.i32_const(0xFFFF);
              b.i32_and();
              return w.NumType.i32;
            case "fromBool":
              codeGen.wrap(value, w.NumType.i32);
              return w.NumType.i32;
            default:
              throw 'Unhandled WasmI32 factory: $name';
          }

        case w.NumType.i64:
          codeGen.wrap(value, w.NumType.i64);
          return w.NumType.i64;
        case w.NumType.f32:
          codeGen.wrap(value, w.NumType.f64);
          b.f32_demote_f64();
          return w.NumType.f32;
        case w.NumType.f64:
          codeGen.wrap(value, w.NumType.f64);
          return w.NumType.f64;
        default:
          w.RefType valueType = targetType as w.RefType;
          codeGen.wrap(value, valueType);
          return valueType;
      }
    }

    // dart:_wasm static functions
    if (node.target.enclosingLibrary.name == "dart._wasm") {
      switch (name) {
        case "_externalizeNonNullable":
          final value = node.arguments.positional.single;
          codeGen.wrap(value, w.RefType.any(nullable: false));
          b.extern_externalize();
          return w.RefType.extern(nullable: false);
        case "_externalizeNullable":
          final value = node.arguments.positional.single;
          codeGen.wrap(value, w.RefType.any(nullable: true));
          b.extern_externalize();
          return w.RefType.extern(nullable: true);
        case "_internalizeNonNullable":
          final value = node.arguments.positional.single;
          codeGen.wrap(value, w.RefType.extern(nullable: false));
          b.extern_internalize();
          return w.RefType.any(nullable: false);
        case "_internalizeNullable":
          final value = node.arguments.positional.single;
          codeGen.wrap(value, w.RefType.extern(nullable: true));
          b.extern_internalize();
          return w.RefType.any(nullable: true);
        case "_wasmExternRefIsNull":
          final value = node.arguments.positional.single;
          codeGen.wrap(value, w.RefType.extern(nullable: true));
          b.ref_is_null();
          return w.NumType.i32;
      }
    }

    return null;
  }

  w.ValueType _changeListClassID(StaticInvocation node, Class newClass) {
    ClassInfo receiverInfo = translator.classInfo[translator.listBaseClass]!;
    codeGen.wrap(
        node.arguments.positional.single, receiverInfo.nonNullableType);
    w.Local receiverLocal =
        codeGen.function.addLocal(receiverInfo.nonNullableType);
    b.local_set(receiverLocal);

    ClassInfo newInfo = translator.classInfo[newClass]!;
    translator.functions.recordClassAllocation(newInfo.classId);
    b.i32_const(newInfo.classId);
    b.i32_const(initialIdentityHash);
    b.local_get(receiverLocal);
    b.struct_get(
        receiverInfo.struct,
        translator.typeParameterIndex[
            translator.listBaseClass.typeParameters.single]!);
    b.local_get(receiverLocal);
    b.struct_get(receiverInfo.struct, FieldIndex.listLength);
    b.local_get(receiverLocal);
    b.struct_get(receiverInfo.struct, FieldIndex.listArray);
    b.struct_new(newInfo.struct);
    return newInfo.nonNullableType;
  }

  /// Generate inline code for a [ConstructorInvocation] if the constructor is
  /// an inlined intrinsic.
  w.ValueType? generateConstructorIntrinsic(ConstructorInvocation node) {
    String name = node.name.text;

    // WasmArray.literal
    final klass = node.target.enclosingClass;
    if (klass == translator.wasmArrayClass && name == "literal") {
      w.ArrayType arrayType =
          translator.arrayTypeForDartType(node.arguments.types.single);
      w.ValueType elementType = arrayType.elementType.type.unpacked;
      Expression value = node.arguments.positional[0];
      List<Expression> elements = value is ListLiteral
          ? value.expressions
          : value is ConstantExpression && value.constant is ListConstant
              ? (value.constant as ListConstant)
                  .entries
                  .map(ConstantExpression.new)
                  .toList()
              : throw "WasmArray.literal argument is not a list literal"
                  " at ${value.location}";
      for (Expression element in elements) {
        codeGen.wrap(element, elementType);
      }
      b.array_new_fixed(arrayType, elements.length);
      return w.RefType.def(arrayType, nullable: false);
    }

    // _Compound.#fromTypedDataBase
    if (name == "#fromTypedDataBase") {
      // A compound (subclass of Struct or Union) is represented by its i32
      // address. The argument to the #fromTypedDataBase constructor is a
      // Pointer, whose representation is the same.
      codeGen.wrap(node.arguments.positional.single, w.NumType.i32);
      return w.NumType.i32;
    }

    return null;
  }

  /// Generate inline code for a [FunctionInvocation] if the function is an
  /// inlined intrinsic.
  w.ValueType? generateFunctionCallIntrinsic(FunctionInvocation node) {
    Expression receiver = node.receiver;

    if (receiver is InstanceGet &&
        receiver.interfaceTarget == translator.wasmFunctionCall) {
      // Receiver is a WasmFunction
      assert(receiver.name.text == "call");
      w.RefType receiverType =
          translator.translateType(dartTypeOf(receiver.receiver)) as w.RefType;
      w.Local temp = codeGen.addLocal(receiverType);
      codeGen.wrap(receiver.receiver, receiverType);
      b.local_set(temp);
      w.FunctionType functionType = receiverType.heapType as w.FunctionType;
      assert(node.arguments.positional.length == functionType.inputs.length);
      for (int i = 0; i < node.arguments.positional.length; i++) {
        codeGen.wrap(node.arguments.positional[i], functionType.inputs[i]);
      }
      b.local_get(temp);
      b.call_ref(functionType);
      return translator.outputOrVoid(functionType.outputs);
    }

    if (receiver is InstanceInvocation &&
        receiver.interfaceTarget == translator.wasmTableCallIndirect) {
      // Receiver is a WasmTable.callIndirect
      assert(receiver.name.text == "callIndirect");
      Expression tableExp = receiver.receiver;
      if (tableExp is! StaticGet || tableExp.target is! Field) {
        throw "Table callIndirect not directly on a static field"
            " at ${node.location}";
      }
      w.Table table = translator.getTable(tableExp.target as Field)!;
      InterfaceType wasmFunctionType = InterfaceType(
          translator.wasmFunctionClass,
          Nullability.nonNullable,
          [receiver.arguments.types.single]);
      w.RefType receiverType =
          translator.translateType(wasmFunctionType) as w.RefType;
      w.Local tableIndex = codeGen.addLocal(w.NumType.i32);
      codeGen.wrap(receiver.arguments.positional.single, w.NumType.i32);
      b.local_set(tableIndex);
      w.FunctionType functionType = receiverType.heapType as w.FunctionType;
      assert(node.arguments.positional.length == functionType.inputs.length);
      for (int i = 0; i < node.arguments.positional.length; i++) {
        codeGen.wrap(node.arguments.positional[i], functionType.inputs[i]);
      }
      b.local_get(tableIndex);
      b.call_indirect(functionType, table);
      return translator.outputOrVoid(functionType.outputs);
    }

    return null;
  }

  /// Generate Wasm function for an intrinsic member.
  bool generateMemberIntrinsic(Reference target, w.FunctionBuilder function,
      List<w.Local> paramLocals, w.Label? returnLabel) {
    Member member = target.asMember;
    if (member is! Procedure) return false;
    String name = member.name.text;
    FunctionNode functionNode = member.function;

    // Object.==
    if (member == translator.coreTypes.objectEquals) {
      b.local_get(paramLocals[0]);
      b.local_get(paramLocals[1]);
      b.ref_eq();
      return true;
    }

    // Object.runtimeType
    if (member.enclosingClass == translator.coreTypes.objectClass &&
        name == "runtimeType") {
      // Simple redirect to `_getMasqueradedRuntimeType`. This is done to keep
      // `Object.runtimeType` external. If `Object.runtimeType` is implemented
      // in Dart, the TFA will conclude that `null.runtimeType` never returns,
      // since it dispatches to `Object.runtimeType`, which uses the receiver
      // as non-nullable.
      w.Local receiver = paramLocals[0];
      b.local_get(receiver);
      codeGen.call(translator.getMasqueradedRuntimeType.reference);
      return true;
    }

    // identical
    if (member == translator.coreTypes.identicalProcedure) {
      w.Local first = paramLocals[0];
      w.Local second = paramLocals[1];
      ClassInfo boolInfo = translator.classInfo[translator.boxedBoolClass]!;
      ClassInfo intInfo = translator.classInfo[translator.boxedIntClass]!;
      ClassInfo doubleInfo = translator.classInfo[translator.boxedDoubleClass]!;
      w.Local cid = function.addLocal(w.NumType.i32);

      // If the references are identical, return true.
      b.local_get(first);
      b.local_get(second);
      b.ref_eq();
      b.if_();
      b.i32_const(1);
      b.return_();
      b.end();

      w.Label fail = b.block();

      // If either is `null`, or their class IDs are different, return false.
      b.local_get(first);
      b.br_on_null(fail);
      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
      b.local_tee(cid);
      b.local_get(second);
      b.br_on_null(fail);
      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
      b.i32_ne();
      b.br_if(fail);

      // Both bool?
      b.local_get(cid);
      b.i32_const(boolInfo.classId);
      b.i32_eq();
      b.if_();
      b.local_get(first);
      b.ref_cast(boolInfo.nonNullableType);
      b.struct_get(boolInfo.struct, FieldIndex.boxValue);
      b.local_get(second);
      b.ref_cast(boolInfo.nonNullableType);
      b.struct_get(boolInfo.struct, FieldIndex.boxValue);
      b.i32_eq();
      b.return_();
      b.end();

      // Both int?
      b.local_get(cid);
      b.i32_const(intInfo.classId);
      b.i32_eq();
      b.if_();
      b.local_get(first);
      b.ref_cast(intInfo.nonNullableType);
      b.struct_get(intInfo.struct, FieldIndex.boxValue);
      b.local_get(second);
      b.ref_cast(intInfo.nonNullableType);
      b.struct_get(intInfo.struct, FieldIndex.boxValue);
      b.i64_eq();
      b.return_();
      b.end();

      // Both double?
      b.local_get(cid);
      b.i32_const(doubleInfo.classId);
      b.i32_eq();
      b.if_();
      b.local_get(first);
      b.ref_cast(doubleInfo.nonNullableType);
      b.struct_get(doubleInfo.struct, FieldIndex.boxValue);
      b.i64_reinterpret_f64();
      b.local_get(second);
      b.ref_cast(doubleInfo.nonNullableType);
      b.struct_get(doubleInfo.struct, FieldIndex.boxValue);
      b.i64_reinterpret_f64();
      b.i64_eq();
      b.return_();
      b.end();

      // Not identical
      b.end(); // fail
      b.i32_const(0);

      return true;
    }

    // _Closure._getClosureRuntimeType
    if (member == translator.getClosureRuntimeType) {
      final w.Local object = paramLocals[0];
      w.StructType closureBase = translator.closureLayouter.closureBaseStruct;
      b.local_get(object);
      b.ref_cast(w.RefType.def(closureBase, nullable: false));
      b.struct_get(closureBase, FieldIndex.closureRuntimeType);
      return true;
    }

    if (member.enclosingLibrary == translator.coreTypes.coreLibrary &&
        name == "identityHashCode") {
      final w.Local arg = paramLocals[0];
      final w.Local nonNullArg =
          function.addLocal(translator.topInfo.nonNullableType);
      final List<int> classIds = translator.valueClasses.keys
          .map((cls) => translator.classInfo[cls]!.classId)
          .toList()
        ..sort();

      // If the argument is `null`, return the hash code of `null`.
      final w.Label notNull =
          b.block(const [], [translator.topInfo.nonNullableType]);
      b.local_get(arg);
      b.br_on_non_null(notNull);
      b.i64_const(null.hashCode);
      b.return_();
      b.end(); // notNull
      b.local_set(nonNullArg);

      // Branch on class ID.
      final w.Label defaultLabel = b.block();
      final List<w.Label> labels =
          List.generate(classIds.length, (_) => b.block());
      b.local_get(nonNullArg);
      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
      int labelIndex = 0;
      final List<w.Label> targets = List.generate(classIds.last + 1, (id) {
        return id == classIds[labelIndex] ? labels[labelIndex++] : defaultLabel;
      });
      b.br_table(targets, defaultLabel);

      // For value classes, dispatch to their `hashCode` implementation.
      for (final int id in classIds.reversed) {
        final Class cls = translator.valueClasses[translator.classes[id].cls!]!;
        final Procedure hashCodeProcedure =
            cls.procedures.firstWhere((p) => p.name.text == "hashCode");
        b.end(); // Jump target for class ID
        b.local_get(nonNullArg);
        codeGen.call(hashCodeProcedure.reference);
        b.return_();
      }

      // For all other classes, dispatch to the `hashCode` implementation in
      // `Object`.
      b.end(); // defaultLabel
      b.local_get(nonNullArg);
      codeGen.call(translator.objectHashCode.reference);
      return true;
    }

    // _typeArguments
    if (name == "_typeArguments" &&
        member.enclosingClass != translator.coreTypes.objectClass) {
      Class cls = member.enclosingClass!;
      ClassInfo classInfo = translator.classInfo[cls]!;
      w.ArrayType arrayType =
          (function.type.outputs.single as w.RefType).heapType as w.ArrayType;
      w.Local object = paramLocals[0];
      w.Local preciseObject = codeGen.addLocal(classInfo.nonNullableType);
      b.local_get(object);
      b.ref_cast(classInfo.nonNullableType);
      b.local_set(preciseObject);
      for (int i = 0; i < cls.typeParameters.length; i++) {
        TypeParameter typeParameter = cls.typeParameters[i];
        int typeParameterIndex = translator.typeParameterIndex[typeParameter]!;
        b.local_get(preciseObject);
        b.struct_get(classInfo.struct, typeParameterIndex);
      }
      b.array_new_fixed(arrayType, cls.typeParameters.length);
      return true;
    }

    // int members
    if (member.enclosingClass == translator.boxedIntClass &&
        member.function.body == null) {
      String op = member.name.text;
      if (functionNode.requiredParameterCount == 0) {
        CodeGenCallback? code = _unaryOperatorMap[intType]![op];
        if (code != null) {
          w.ValueType resultType = _unaryResultMap[op] ?? intType;
          w.ValueType inputType = function.type.inputs.single;
          w.ValueType outputType = function.type.outputs.single;
          b.local_get(function.locals[0]);
          translator.convertType(function, inputType, intType);
          code(codeGen);
          translator.convertType(function, resultType, outputType);
          return true;
        }
      } else if (functionNode.requiredParameterCount == 1) {
        CodeGenCallback? code = _binaryOperatorMap[intType]![intType]![op];
        if (code != null) {
          w.ValueType leftType = function.type.inputs[0];
          w.ValueType rightType = function.type.inputs[1];
          w.ValueType outputType = function.type.outputs.single;
          if (rightType == intType) {
            // int parameter
            b.local_get(function.locals[0]);
            translator.convertType(function, leftType, intType);
            b.local_get(function.locals[1]);
            code(codeGen);
            if (!isComparison(op)) {
              translator.convertType(function, intType, outputType);
            }
            return true;
          }
          // num parameter
          ClassInfo intInfo = translator.classInfo[translator.boxedIntClass]!;
          w.Label intArg = b.block(const [], [intInfo.nonNullableType]);
          b.local_get(function.locals[1]);
          b.br_on_cast(intArg, function.locals[1].type as w.RefType,
              intInfo.nonNullableType);
          // double argument
          b.drop();
          b.local_get(function.locals[0]);
          translator.convertType(function, leftType, intType);
          b.f64_convert_i64_s();
          b.local_get(function.locals[1]);
          translator.convertType(function, rightType, doubleType);
          // Inline double op
          CodeGenCallback doubleCode =
              _binaryOperatorMap[doubleType]![doubleType]![op]!;
          doubleCode(codeGen);
          if (!isComparison(op)) {
            translator.convertType(function, doubleType, outputType);
          }
          b.return_();
          b.end();
          // int argument
          translator.convertType(function, intInfo.nonNullableType, intType);
          w.Local rightTemp = function.addLocal(intType);
          b.local_set(rightTemp);
          b.local_get(function.locals[0]);
          translator.convertType(function, leftType, intType);
          b.local_get(rightTemp);
          code(codeGen);
          if (!isComparison(op)) {
            translator.convertType(function, intType, outputType);
          }
          return true;
        }
      }
    }

    // double unary members
    if (member.enclosingClass == translator.boxedDoubleClass &&
        member.function.body == null) {
      String op = member.name.text;
      if (functionNode.requiredParameterCount == 0) {
        CodeGenCallback? code = _unaryOperatorMap[doubleType]![op];
        if (code != null) {
          w.ValueType resultType = _unaryResultMap[op] ?? doubleType;
          w.ValueType inputType = function.type.inputs.single;
          w.ValueType outputType = function.type.outputs.single;
          b.local_get(function.locals[0]);
          translator.convertType(function, inputType, doubleType);
          code(codeGen);
          translator.convertType(function, resultType, outputType);
          return true;
        }
      }
    }

    if (member.enclosingClass == translator.closureClass && name == "_equals") {
      // Function equality works like this:
      //
      // - Function literals and local functions are only equal if they're the
      //   same reference.
      //
      // - Instance tear-offs are equal if they are tear-offs of the same
      //   method on the same object.
      //
      // - Tear-offs of static methods and top-level functions are identical
      //   (and thus equal) when they are tear-offs of the same function. Generic
      //   instantiations of these are identical when the tear-offs are identical
      //   and they are instantiated with identical types.
      //
      // To distinguish a function literal or local function from an instance
      // tear-off we check type of the context:
      //
      // - If context's type is a subtype of the top type for Dart objects then
      //   the function is a tear-off and we compare the context using the
      //   `identical` function.
      //
      //   The reason why we use `identical` (instead of `ref.eq`) is to handle
      //   bool, double, and int receivers in code like `1.toString ==
      //   1.toString`, which should evaluate to `true` even if the receivers
      //   do not point to the same Wasm object.
      //
      // - Otherwise the function is a function literal or local function.
      //
      // In pseudo code:
      //
      //   bool _equals(f1, f2) {
      //     if (identical(f1, f2) return true;
      //
      //     if (<f1 and f2 are instantiations>
      //           ? f1.context.inner.vtable != f2.context.inner.vtable
      //           : f1.vtable != f2.vtable) {
      //       return false;
      //     }
      //
      //     if (<f1 and f2 are instantiations>) {
      //       if (typesEqual(f1.context, f2.context)) {
      //         f1 = f1.context.inner;
      //         f2 = f2.context.inner;
      //         if (identical(f1, f2)) return true;
      //         goto outerClosureContext;
      //       }
      //       return false;
      //     }
      //
      //     outerClosureContext:
      //     if (f1.context is #Top && f2.context is #Top) {
      //       return identical(f1.context, f2.context);
      //     }
      //
      //     return false;
      //   }

      // Check if the arguments are the same
      b.local_get(function.locals[0]);
      b.local_get(function.locals[1]);
      b.ref_eq();
      b.if_();
      b.i32_const(1); // true
      b.return_();
      b.end();

      // Arguments are different, compare context and vtable references
      final w.StructType closureBaseStruct =
          translator.closureLayouter.closureBaseStruct;
      final w.RefType closureBaseStructRef =
          w.RefType.def(closureBaseStruct, nullable: false);

      final w.Local fun1 = codeGen.function.addLocal(closureBaseStructRef);
      b.local_get(function.locals[0]);
      translator.convertType(
          function, function.locals[0].type, closureBaseStructRef);
      b.local_set(fun1);

      final w.Local fun2 = codeGen.function.addLocal(closureBaseStructRef);
      b.local_get(function.locals[1]);
      translator.convertType(
          function, function.locals[1].type, closureBaseStructRef);
      b.local_set(fun2);

      // Compare vtable references. For instantiation closures compare the
      // inner vtables
      final instantiationContextBase = w.RefType(
          translator.closureLayouter.instantiationContextBaseStruct,
          nullable: false);
      final vtableRefType = w.RefType.def(
          translator.closureLayouter.vtableBaseStruct,
          nullable: false);
      // Returns vtables of closures that we compare for equality.
      final vtablesBlock = b.block([], [vtableRefType, vtableRefType]);
      // `br` target when fun1 is not an instantiation
      final fun1NotInstantiationBlock =
          b.block([], [w.RefType.struct(nullable: false)]);
      // `br` target when fun1 is an instantiation, but fun2 is not
      final fun1InstantiationFun2NotInstantiationBlock =
          b.block([], [w.RefType.struct(nullable: false)]);
      b.local_get(fun1);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.br_on_cast_fail(fun1NotInstantiationBlock,
          const w.RefType.struct(nullable: false), instantiationContextBase);
      b.struct_get(translator.closureLayouter.instantiationContextBaseStruct,
          FieldIndex.instantiationContextInner);
      b.struct_get(closureBaseStruct, FieldIndex.closureVtable);
      b.local_get(fun2);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.br_on_cast_fail(fun1InstantiationFun2NotInstantiationBlock,
          const w.RefType.struct(nullable: false), instantiationContextBase);
      b.struct_get(translator.closureLayouter.instantiationContextBaseStruct,
          FieldIndex.instantiationContextInner);
      b.struct_get(closureBaseStruct, FieldIndex.closureVtable);
      b.br(vtablesBlock);
      b.end(); // fun1InstantiationFun2NotInstantiationBlock
      b.i32_const(0); // false
      b.return_();
      b.end(); // fun1NotInstantiationBlock
      b.drop();
      b.local_get(fun1);
      b.struct_get(closureBaseStruct, FieldIndex.closureVtable);
      // To keep the generated code small and simple, instead of checking that
      // fun2 is also not an instantiation, we can just return the outer
      // (potentially instantiation) vtable here. In the rest of the code
      // `ref.eq` will be `false` (as vtable of an instantiation and
      // non-instantiation will never be equal) and the function will return
      // `false` as expected.
      b.local_get(fun2);
      b.struct_get(closureBaseStruct, FieldIndex.closureVtable);
      b.end(); // vtablesBlock
      b.ref_eq();

      b.if_(); // fun1.vtable == fun2.vtable

      // Check if closures are instantiations. Since they have the same vtable
      // it's enough to check just one of them.
      final instantiationCheckPassedBlock = b.block();

      final notInstantiationBlock =
          b.block([], [w.RefType.struct(nullable: false)]);

      b.local_get(fun1);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.br_on_cast_fail(notInstantiationBlock,
          const w.RefType.struct(nullable: false), instantiationContextBase);

      // Closures are instantiations. Compare inner function vtables to check
      // that instantiations are for the same generic function.
      void getInstantiationContextInner(w.Local fun) {
        b.local_get(fun);
        // instantiation.context
        b.struct_get(closureBaseStruct, FieldIndex.closureContext);
        b.ref_cast(instantiationContextBase);
        // instantiation.context.inner
        b.struct_get(translator.closureLayouter.instantiationContextBaseStruct,
            FieldIndex.instantiationContextInner);
      }

      // Closures are instantiations of the same function, compare types.
      b.local_get(fun1);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.ref_cast(instantiationContextBase);
      b.local_get(fun2);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.ref_cast(instantiationContextBase);
      getInstantiationContextInner(fun1);
      b.struct_get(closureBaseStruct, FieldIndex.closureVtable);
      b.ref_cast(w.RefType.def(
          translator.closureLayouter.genericVtableBaseStruct,
          nullable: false));
      b.struct_get(translator.closureLayouter.genericVtableBaseStruct,
          FieldIndex.vtableInstantiationTypeComparisonFunction);
      b.call_ref(translator
          .closureLayouter.instantiationClosureTypeComparisonFunctionType);
      b.if_();
      getInstantiationContextInner(fun1);
      b.local_tee(fun1);
      getInstantiationContextInner(fun2);
      b.local_tee(fun2);
      b.ref_eq();
      b.if_();
      b.i32_const(1); // true
      b.return_();
      b.end();
      b.br(instantiationCheckPassedBlock);
      b.end();
      b.i32_const(0); // false
      b.return_();
      b.i32_const(0); // false
      b.return_();
      b.end(); // notInstantiationBlock
      b.drop();
      b.end(); // instantiationCheckPassedBlock

      // Compare context references. If context of a function has the top type
      // then the function is an instance tear-off. Otherwise it's a closure.
      final contextCheckFail = b.block([], [w.RefType.struct(nullable: false)]);
      b.local_get(fun1);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.br_on_cast_fail(
          contextCheckFail,
          const w.RefType.struct(nullable: false),
          translator.topInfo.nonNullableType);

      b.local_get(fun2);
      b.struct_get(closureBaseStruct, FieldIndex.closureContext);
      b.br_on_cast_fail(
          contextCheckFail,
          const w.RefType.struct(nullable: false),
          translator.topInfo.nonNullableType);

      // Both contexts are objects, compare for equality with `identical`. This
      // handles identical `this` values in instance tear-offs.
      codeGen.call(translator.coreTypes.identicalProcedure.reference);
      b.return_();
      b.end(); // contextCheckFail

      b.i32_const(0); // false
      b.return_();

      b.end(); // fun1.vtable == fun2.vtable

      b.i32_const(0); // false

      return true;
    }

    if (member.enclosingClass == translator.coreTypes.functionClass &&
        name == "apply") {
      assert(function.type.inputs.length == 3);

      final closureLocal = function.locals[0]; // ref #ClosureBase
      final posArgsNullableLocal = function.locals[1]; // ref null Object,
      final namedArgsLocal = function.locals[2]; // ref null Object

      // Create empty type arguments array.
      final typeArgsLocal = function.addLocal(translator.makeArray(function,
          translator.typeArrayType, 0, (elementType, elementIndex) {}));
      b.local_set(typeArgsLocal);

      // Create empty list for positional args if the argument is null
      final posArgsLocal =
          function.addLocal(translator.nullableObjectArrayTypeRef);
      b.local_get(posArgsNullableLocal);
      b.ref_is_null();

      b.if_([], [translator.nullableObjectArrayTypeRef]);
      translator.makeArray(
          function, translator.nullableObjectArrayType, 0, (_, __) {});

      b.else_();
      // List argument may be a custom list type, convert it to `_ListBase`
      // with `_List.of`.
      translator.constants.instantiateConstant(
        function,
        b,
        TypeLiteralConstant(DynamicType()),
        translator.types.nonNullableTypeType,
      );
      b.local_get(posArgsNullableLocal);
      b.ref_as_non_null();
      codeGen.call(translator.listOf.reference);
      translator.getListBaseArray(b);
      b.end();
      b.local_set(posArgsLocal);

      // Convert named argument map to list, to be passed to shape and type
      // checkers and the dynamic call entry.
      final namedArgsListLocal =
          function.addLocal(translator.nullableObjectArrayTypeRef);
      b.local_get(namedArgsLocal);
      codeGen.call(translator.namedParameterMapToArray.reference);
      b.local_set(namedArgsListLocal);

      final noSuchMethodBlock = b.block();

      generateDynamicFunctionCall(translator, function, closureLocal,
          typeArgsLocal, posArgsLocal, namedArgsListLocal, noSuchMethodBlock);
      b.return_();

      b.end(); // noSuchMethodBlock

      generateNoSuchMethodCall(
          translator,
          function,
          () => b.local_get(closureLocal),
          () => createInvocationObject(translator, function, "call",
              typeArgsLocal, posArgsLocal, namedArgsListLocal));

      return true;
    }

    // Error._throw
    if (member.enclosingClass == translator.errorClass && name == "_throw") {
      final objectLocal = function.locals[0]; // ref #Top
      final stackTraceLocal = function.locals[1]; // ref Object

      final notErrorBlock = b.block([], [objectLocal.type]);

      final errorClassInfo = translator.classInfo[translator.errorClass]!;
      final errorRefType = errorClassInfo.nonNullableType;
      final stackTraceFieldIndex =
          translator.fieldIndex[translator.errorClassStackTraceField]!;
      b.local_get(objectLocal);
      b.br_on_cast_fail(
          notErrorBlock, objectLocal.type as w.RefType, errorRefType);

      final errorLocal = function.addLocal(errorRefType);
      b.local_tee(errorLocal);

      b.struct_get(errorClassInfo.struct, stackTraceFieldIndex);
      b.ref_is_null();
      b.if_();
      b.local_get(errorLocal);
      b.local_get(stackTraceLocal);
      b.struct_set(errorClassInfo.struct, stackTraceFieldIndex);
      b.end();

      b.local_get(objectLocal);
      b.end(); // notErrorBlock

      b.local_get(stackTraceLocal);
      b.throw_(translator.exceptionTag);

      return true;
    }

    if (member.enclosingClass == translator.wasmExternRefClass &&
        name == "nullRef") {
      b.ref_null(w.HeapType.noextern);
      return true;
    }

    return false;
  }
}
