// 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:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:wasm_builder/wasm_builder.dart' as w;

import 'abi.dart' show kWasmAbiEnumIndex;
import 'class_info.dart';
import 'code_generator.dart';
import 'dynamic_forwarders.dart';
import 'dynamic_modules.dart';
import 'translator.dart';
import 'types.dart';
import 'util.dart';

typedef CodeGenCallback = void Function(AstCodeGenerator);

typedef InlineCodeGenCallback = void Function(
    AstCodeGenerator, Expression receiver);

enum MemberIntrinsic {
  objectEquals('dart:core', 'Object', '=='),
  objectRuntimeType('dart:core', 'Object', 'runtimeType'),
  identical('dart:core', null, 'identical'),
  closureRuntimeType('dart:core', '_Closure', '_getClosureRuntimeType'),
  identityHashCode('dart:core', null, 'identityHashCode'),
  typeArguments('dart:core', '', ''),
  intAdd('dart:_boxed_int', 'BoxedInt', '+'),
  intSub('dart:_boxed_int', 'BoxedInt', '-'),
  intMul('dart:_boxed_int', 'BoxedInt', '*'),
  intAnd('dart:_boxed_int', 'BoxedInt', '&'),
  intOr('dart:_boxed_int', 'BoxedInt', '|'),
  intXor('dart:_boxed_int', 'BoxedInt', '^'),
  intLt('dart:_boxed_int', 'BoxedInt', '<'),
  intGt('dart:_boxed_int', 'BoxedInt', '>'),
  intLe('dart:_boxed_int', 'BoxedInt', '<='),
  intGe('dart:_boxed_int', 'BoxedInt', '>='),
  intNeg('dart:_boxed_int', 'BoxedInt', 'unary-'),
  intInv('dart:_boxed_int', 'BoxedInt', '~'),
  intToDouble('dart:_boxed_int', 'BoxedInt', 'toDouble'),
  doubleNeg('dart:_boxed_double', 'BoxedDouble', 'unary-'),
  doubleFloorToDouble('dart:_boxed_double', 'BoxedDouble', 'floorToDouble'),
  doubleCeilToDouble('dart:_boxed_double', 'BoxedDouble', 'ceilToDouble'),
  doubleTruncateToDouble(
      'dart:_boxed_double', 'BoxedDouble', 'truncateToDouble'),
  isInstantiationClosure('dart:core', '_Closure', '_isInstantiationClosure'),
  instantiatedClosure('dart:core', '_Closure', '_instantiatedClosure'),
  instantiationClosureTypeHash(
      'dart:core', '_Closure', '_instantiationClosureTypeHash'),
  instantiationClosureTypeEquals(
      'dart:core', '_Closure', '_instantiationClosureTypeEquals'),
  isInstanceTearOff('dart:core', '_Closure', '_isInstanceTearOff'),
  instanceTearOffReceiver('dart:core', '_Closure', '_instanceTearOffReceiver'),
  vtable('dart:core', '_Closure', '_vtable'),
  functionApply('dart:core', 'Function', 'apply'),
  errorThrow('dart:core', 'Error', '_throw'),
  nullRef('dart:_wasm', 'WasmExternRef', 'nullRef');

  final String library;
  final String? cls;
  final String name;

  const MemberIntrinsic(this.library, this.cls, this.name);

  static Map<String, Map<String?, Map<String, MemberIntrinsic>>>? _lookup;

  static Map<String, Map<String?, Map<String, MemberIntrinsic>>>
      _populateLookup() {
    final result = <String, Map<String?, Map<String, MemberIntrinsic>>>{};
    for (var intrinsic in MemberIntrinsic.values) {
      ((result[intrinsic.library] ??= {})[intrinsic.cls] ??=
          {})[intrinsic.name] = intrinsic;
    }
    return result;
  }

  static MemberIntrinsic? fromProcedure(CoreTypes coreTypes, Procedure member) {
    if (member.name.text == '_typeArguments' &&
        hasPragma(coreTypes, member, 'wasm:intrinsic')) {
      return MemberIntrinsic.typeArguments;
    }
    final intrinsic = (_lookup ??=
            _populateLookup())['${member.enclosingLibrary.importUri}']
        ?[member.enclosingClass?.name]?[member.name.text];
    assert(intrinsic == null || hasPragma(coreTypes, member, 'wasm:intrinsic'));
    return intrinsic;
  }
}

enum StaticIntrinsic {
  wasmArrayNew('dart:_wasm', 'WasmArray', ''),
  wasmArrayFilled('dart:_wasm', 'WasmArray', 'filled'),
  wasmArrayIndex('dart:_wasm', null, 'WasmArrayExt|[]'),
  wasmArrayIndexSet('dart:_wasm', null, 'WasmArrayExt|[]='),
  wasmArrayCopy('dart:_wasm', null, 'WasmArrayExt|copy'),
  wasmArrayFill('dart:_wasm', null, 'WasmArrayExt|fill'),
  wasmArrayClone('dart:_wasm', null, 'WasmArrayExt|clone'),
  immutableWasmArrayNew('dart:_wasm', 'ImmutableWasmArray', ''),
  immutableWasmArrayFilled('dart:_wasm', 'ImmutableWasmArray', 'filled'),
  immutableWasmArrayIndex('dart:_wasm', null, 'ImmutableWasmArrayExt|[]'),
  i64ArrayExtRead('dart:_wasm', null, 'I64ArrayExt|read'),
  f32ArrayExtRead('dart:_wasm', null, 'F32ArrayExt|read'),
  f64ArrayExtRead('dart:_wasm', null, 'F64ArrayExt|read'),
  immutableI64ArrayExtRead('dart:_wasm', null, 'ImmutableI64ArrayExt|read'),
  immutableF32ArrayExtRead('dart:_wasm', null, 'ImmutableF32ArrayExt|read'),
  immutableF64ArrayExtRead('dart:_wasm', null, 'ImmutableF64ArrayExt|read'),
  i8ArrayExtReadSigned('dart:_wasm', null, 'I8ArrayExt|readSigned'),
  i16ArrayExtReadSigned('dart:_wasm', null, 'I16ArrayExt|readSigned'),
  i32ArrayExtReadSigned('dart:_wasm', null, 'I32ArrayExt|readSigned'),
  immutableI8ArrayExtReadSigned(
      'dart:_wasm', null, 'ImmutableI8ArrayExt|readSigned'),
  immutableI16ArrayExtReadSigned(
      'dart:_wasm', null, 'ImmutableI16ArrayExt|readSigned'),
  immutableI32ArrayExtReadSigned(
      'dart:_wasm', null, 'ImmutableI32ArrayExt|readSigned'),
  i8ArrayExtReadUnsigned('dart:_wasm', null, 'I8ArrayExt|readUnsigned'),
  i16ArrayExtReadUnsigned('dart:_wasm', null, 'I16ArrayExt|readUnsigned'),
  i32ArrayExtReadUnsigned('dart:_wasm', null, 'I32ArrayExt|readUnsigned'),
  immutableI8ArrayExtReadUnsigned(
      'dart:_wasm', null, 'ImmutableI8ArrayExt|readUnsigned'),
  immutableI16ArrayExtReadUnsigned(
      'dart:_wasm', null, 'ImmutableI16ArrayExt|readUnsigned'),
  immutableI32ArrayExtReadUnsigned(
      'dart:_wasm', null, 'ImmutableI32ArrayExt|readUnsigned'),
  i8ArrayExtWrite('dart:_wasm', null, 'I8ArrayExt|write'),
  i16ArrayExtWrite('dart:_wasm', null, 'I16ArrayExt|write'),
  i32ArrayExtWrite('dart:_wasm', null, 'I32ArrayExt|write'),
  i64ArrayExtWrite('dart:_wasm', null, 'I64ArrayExt|write'),
  f32ArrayExtWrite('dart:_wasm', null, 'F32ArrayExt|write'),
  f64ArrayExtWrite('dart:_wasm', null, 'F64ArrayExt|write'),
  wasmFunctionFromFuncRef('dart:_wasm', 'WasmFunction', 'fromFuncRef'),
  wasmFunctionFromFunction('dart:_wasm', 'WasmFunction', 'fromFunction'),
  wasmI32FromInt('dart:_wasm', 'WasmI32', 'fromInt'),
  wasmI32Int8FromInt('dart:_wasm', 'WasmI32', 'int8FromInt'),
  wasmI32Uint8FromInt('dart:_wasm', 'WasmI32', 'uint8FromInt'),
  wasmI32Int16FromInt('dart:_wasm', 'WasmI32', 'int16FromInt'),
  wasmI32Uint16FromInt('dart:_wasm', 'WasmI32', 'uint16FromInt'),
  wasmI32FromBool('dart:_wasm', 'WasmI32', 'fromBool'),
  wasmI64FromInt('dart:_wasm', 'WasmI64', 'fromInt'),
  wasmF32FromDouble('dart:_wasm', 'WasmF32', 'fromDouble'),
  wasmF64FromDouble('dart:_wasm', 'WasmF64', 'fromDouble'),
  wasmAnyRefFromObject('dart:_wasm', 'WasmAnyRef', 'fromObject'),
  wasmFuncRefFromWasmFunction('dart:_wasm', 'WasmFuncRef', 'fromWasmFunction'),
  wasmEqRefFromObject('dart:_wasm', 'WasmEqRef', 'fromObject'),
  wasmStructRefFromObject('dart:_wasm', 'WasmStructRef', 'fromObject'),
  externalizeNonNullable('dart:_wasm', null, '_externalizeNonNullable'),
  externalizeNullable('dart:_wasm', null, '_externalizeNullable'),
  internalizeNonNullable('dart:_wasm', null, '_internalizeNonNullable'),
  internalizeNullable('dart:_wasm', null, '_internalizeNullable'),
  wasmExternRefIsNull('dart:_wasm', null, '_wasmExternRefIsNull'),
  isSubClassOf('dart:_wasm', null, 'isSubClassOf'),
  identical('dart:core', null, 'identical'),
  isObjectClassId('dart:core', null, '_isObjectClassId'),
  isClosureClassId('dart:core', null, '_isClosureClassId'),
  isRecordClassId('dart:core', null, '_isRecordClassId'),
  getIdentityHashField('dart:_object_helper', null, 'getIdentityHashField'),
  setIdentityHashField('dart:_object_helper', null, 'setIdentityHashField'),
  unsafeCast('dart:_internal', null, 'unsafeCast'),
  unsafeCastOpaque('dart:_internal', null, 'unsafeCastOpaque'),
  nativeEffect('dart:_internal', null, '_nativeEffect'),
  floatToIntBits('dart:_internal', null, 'floatToIntBits'),
  intBitsToFloat('dart:_internal', null, 'intBitsToFloat'),
  doubleToIntBits('dart:_internal', null, 'doubleToIntBits'),
  intBitsToDouble('dart:_internal', null, 'intBitsToDouble'),
  exportWasmFunction('dart:_internal', null, 'exportWasmFunction'),
  getID('dart:_internal', 'ClassID', 'getID'),
  loadInt8('dart:ffi', null, '_loadInt8'),
  loadUint8('dart:ffi', null, '_loadUint8'),
  loadInt16('dart:ffi', null, '_loadInt16'),
  loadUint16('dart:ffi', null, '_loadUint16'),
  loadInt32('dart:ffi', null, '_loadInt32'),
  loadUint32('dart:ffi', null, '_loadUint32'),
  loadInt64('dart:ffi', null, '_loadInt64'),
  loadUint64('dart:ffi', null, '_loadUint64'),
  loadFloat('dart:ffi', null, '_loadFloat'),
  loadFloatUnaligned('dart:ffi', null, '_loadFloatUnaligned'),
  loadDouble('dart:ffi', null, '_loadDouble'),
  loadDoubleUnaligned('dart:ffi', null, '_loadDoubleUnaligned'),
  storeInt8('dart:ffi', null, '_storeInt8'),
  storeUint8('dart:ffi', null, '_storeUint8'),
  storeInt16('dart:ffi', null, '_storeInt16'),
  storeUint16('dart:ffi', null, '_storeUint16'),
  storeInt32('dart:ffi', null, '_storeInt32'),
  storeUint32('dart:ffi', null, '_storeUint32'),
  storeInt64('dart:ffi', null, '_storeInt64'),
  storeUint64('dart:ffi', null, '_storeUint64'),
  storeFloat('dart:ffi', null, '_storeFloat'),
  storeFloatUnaligned('dart:ffi', null, '_storeFloatUnaligned'),
  storeDouble('dart:ffi', null, '_storeDouble'),
  storeDoubleUnaligned('dart:ffi', null, '_storeDoubleUnaligned'),
  wasmI31RefNew('dart:_wasm', 'WasmI31Ref', 'fromI32'),
  wasmI31RefExtensionsExternalize(
      'dart:_wasm', null, 'WasmI31RefExtensions|externalize'),
  wasmI31RefExtensionsGetS('dart:_wasm', null, 'WasmI31RefExtensions|get_s'),
  wasmI31RefExtensionsGetU('dart:_wasm', null, 'WasmI31RefExtensions|get_u');

  final String library;
  final String? cls;
  final String name;

  const StaticIntrinsic(this.library, this.cls, this.name);

  static Map<String, Map<String?, Map<String, StaticIntrinsic>>>? _lookup;

  static Map<String, Map<String?, Map<String, StaticIntrinsic>>>
      _populateLookup() {
    final result = <String, Map<String?, Map<String, StaticIntrinsic>>>{};
    for (var intrinsic in StaticIntrinsic.values) {
      ((result[intrinsic.library] ??= {})[intrinsic.cls] ??=
          {})[intrinsic.name] = intrinsic;
    }
    return result;
  }

  static StaticIntrinsic? fromProcedure(CoreTypes coreTypes, Procedure member) {
    final intrinsic = (_lookup ??=
            _populateLookup())['${member.enclosingLibrary.importUri}']
        ?[member.enclosingClass?.name]?[member.name.text];
    assert(intrinsic == null || hasPragma(coreTypes, member, 'wasm:intrinsic'));
    return intrinsic;
  }
}

/// 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 AstCodeGenerator 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(),
        '~/': (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(),
      }
    },
  };

  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();
      },
    },
  };

  static final Map<w.ValueType, Map<String, InlineCodeGenCallback>>
      _inlineUnaryOperatorMap = {
    intType: {
      'unary-': (c, receiver) {
        final int? intValue = _extractIntValue(receiver);
        if (intValue == null) {
          c.translateExpression(receiver, intType);
          c.b.i64_const(-1);
          c.b.i64_mul();
        } else {
          c.b.i64_const(-intValue);
        }
      },
      '~': (c, receiver) {
        final int? intValue = _extractIntValue(receiver);
        if (intValue == null) {
          c.translateExpression(receiver, intType);
          c.b.i64_const(-1);
          c.b.i64_xor();
        } else {
          c.b.i64_const(~intValue);
        }
      },
      'toDouble': (c, receiver) {
        final int? intValue = _extractIntValue(receiver);
        if (intValue == null) {
          c.translateExpression(receiver, intType);
          c.b.f64_convert_i64_s();
        } else {
          c.b.f64_const(intValue.toDouble());
        }
      },
    },
    doubleType: {
      'unary-': (c, receiver) {
        final double? doubleValue = _extractDoubleValue(receiver);
        if (doubleValue == null) {
          c.translateExpression(receiver, doubleType);
          c.b.f64_neg();
        } else {
          c.b.f64_const(-doubleValue);
        }
      },
      'floorToDouble': (c, receiver) {
        final double? doubleValue = _extractDoubleValue(receiver);
        if (doubleValue == null) {
          c.translateExpression(receiver, doubleType);
          c.b.f64_floor();
        } else {
          c.b.f64_const(doubleValue.floorToDouble());
        }
      },
      'ceilToDouble': (c, receiver) {
        final double? doubleValue = _extractDoubleValue(receiver);
        if (doubleValue == null) {
          c.translateExpression(receiver, doubleType);
          c.b.f64_ceil();
        } else {
          c.b.f64_const(doubleValue.ceilToDouble());
        }
      },
      'truncateToDouble': (c, receiver) {
        final double? doubleValue = _extractDoubleValue(receiver);
        if (doubleValue == null) {
          c.translateExpression(receiver, doubleType);
          c.b.f64_trunc();
        } else {
          c.b.f64_const(doubleValue.truncateToDouble());
        }
      },
    },
  };

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

  Translator get translator => codeGen.translator;
  Types get types => codeGen.translator.types;
  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, WasmAnyRef.isI31
    if (cls == translator.wasmAnyRefClass) {
      if (name == "isObject") {
        codeGen.translateExpression(receiver, w.RefType.any(nullable: false));
        b.ref_test(translator.topTypeNonNullable);
        return w.NumType.i32;
      } else if (name == "isI31") {
        codeGen.translateExpression(receiver, w.RefType.any(nullable: false));
        b.ref_test(w.RefType.i31(nullable: false));
        return w.NumType.i32;
      }
    }

    // WasmArrayRef.length
    if (cls == translator.wasmArrayRefClass) {
      assert(name == 'length');
      codeGen.translateExpression(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(b.moduleBuilder, 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 = b.addLocal(w.NumType.i64);
      b.i64_const(64);
      codeGen.translateExpression(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;
    }

    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.topTypeNonNullable]);
      codeGen.translateExpression(
          receiver, const w.RefType.any(nullable: false));
      b.br_on_cast(succeed, const w.RefType.any(nullable: false),
          translator.topTypeNonNullable);
      codeGen.throwWasmRefError("a Dart object");
      b.end(); // succeed
      return translator.topTypeNonNullable;
    }

    // Wasm(I32|I64|F32|F64) conversions
    if (cls.superclass == translator.wasmTypesBaseClass) {
      w.StorageType? receiverType = translator.builtinTypes[cls];
      switch (receiverType) {
        case w.NumType.i32:
          switch (name) {
            case "unary-":
              b.i32_const(0);
              codeGen.translateExpression(receiver, w.NumType.i32);
              b.i32_sub();
              return w.NumType.i32;
          }
          codeGen.translateExpression(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;
          }
          codeGen.translateExpression(
              node.arguments.positional[0], 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;
            case "+":
              b.i32_add();
              return w.NumType.i32;
            case "-":
              b.i32_sub();
              return w.NumType.i32;
            case ">>":
              b.i32_shr_s();
              return w.NumType.i32;
            case "<":
              b.i32_lt_s();
              return boolType;
            case "<=":
              b.i32_le_s();
              return boolType;
            case "==":
              b.i32_eq();
              return boolType;
            case ">=":
              b.i32_ge_s();
              return boolType;
            case ">":
              b.i32_gt_s();
              return boolType;
            case "leU":
              b.i32_le_u();
              return boolType;
            case "ltU":
              b.i32_lt_u();
              return boolType;
            case "geU":
              b.i32_ge_u();
              return boolType;
            case "gtU":
              b.i32_gt_u();
              return boolType;
            default:
              throw 'Unknown WasmI32 member $name';
          }
        case w.NumType.i64:
          switch (name) {
            case "toInt":
              codeGen.translateExpression(receiver, w.NumType.i64);
              return w.NumType.i64;
            case "leU":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_le_u();
              return boolType;
            case "ltU":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_lt_u();
              return boolType;
            case "geU":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_ge_u();
              return boolType;
            case "gtU":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_gt_u();
              return boolType;
            case "shl":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_shl();
              return w.NumType.i64;
            case "shrS":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_shr_s();
              return w.NumType.i64;
            case "shrU":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_shr_u();
              return w.NumType.i64;
            case "divS":
              codeGen.translateExpression(receiver, w.NumType.i64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.i64);
              b.i64_div_s();
              return w.NumType.i64;
            default:
              throw 'Unknown WasmI64 member $name';
          }
        case w.NumType.f32:
          assert(name == "toDouble");
          codeGen.translateExpression(receiver, w.NumType.f32);
          b.f64_promote_f32();
          return w.NumType.f64;
        case w.NumType.f64:
          switch (name) {
            case "toDouble":
              codeGen.translateExpression(receiver, w.NumType.f64);
              return w.NumType.f64;
            case "truncSatS":
              codeGen.translateExpression(receiver, w.NumType.f64);
              b.i64_trunc_sat_f64_s();
              return w.NumType.i64;
            case "sqrt":
              codeGen.translateExpression(receiver, w.NumType.f64);
              b.f64_sqrt();
              return w.NumType.f64;
            case "copysign":
              codeGen.translateExpression(receiver, w.NumType.f64);
              codeGen.translateExpression(
                  node.arguments.positional[0], w.NumType.f64);
              b.f64_copysign();
              return w.NumType.f64;
            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(b.moduleBuilder, receiver.target as Field)!;
      codeGen.translateExpression(node.arguments.positional[0], w.NumType.i32);
      if (name == '[]') {
        b.table_get(table);
        return table.type;
      } else {
        assert(name == '[]=');
        codeGen.translateExpression(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;
      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) {
        final entries = (receiver.constant as ListConstant).entries;
        if (0 <= constIndex && constIndex < entries.length) {
          Expression element = ConstantExpression(entries[constIndex]);
          return codeGen.translateExpression(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.translateExpression(left, leftType);
        codeGen.translateExpression(right, rightType);
        code(codeGen);
        return outType;
      }
    } else if (node.arguments.positional.isEmpty) {
      // Unary operator
      Expression operand = node.receiver;
      w.ValueType operandType = translator.translateType(receiverType);
      var code = _inlineUnaryOperatorMap[operandType]?[name];
      if (code != null) {
        code(codeGen, operand);
        return _unaryResultMap[name] ?? operandType;
      }
    }

    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 or WasmI32.
    if (leftType == w.NumType.i32 && rightType == w.NumType.i32) {
      codeGen.translateExpression(node.left, w.NumType.i32);
      codeGen.translateExpression(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.translateExpression(node.left, w.NumType.i64);
      codeGen.translateExpression(node.right, w.NumType.i64);
      b.i64_eq();
      return w.NumType.i32;
    }

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

    // Compare double or WasmF64.
    if (leftType == doubleType && rightType == doubleType) {
      codeGen.translateExpression(node.left, w.NumType.f64);
      codeGen.translateExpression(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') {
      if (target.name.text == 'maxClassId') {
        codeGen.b.i32_const(translator.classIdNumbering.maxClassId);
        return w.NumType.i32;
      }
      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})');
        ClassId classId = translator.classInfo[cls]!.classId;
        b.pushClassIdToStack(translator, classId);
        return w.NumType.i32;
      }

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

    if (target.enclosingLibrary.name == 'dart._internal') {
      if (target.name.text == '_numClassesForConstCaches') {
        b.i64_const(translator.classIdNumbering.maxClassId);
        return w.NumType.i64;
      }
    }

    if (node.target.enclosingLibrary == translator.coreTypes.coreLibrary) {
      switch (target.name.text) {
        case "_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;
        case "_noSubstitutionIndex":
          b.i32_const(RuntimeTypeInformation.noSubstitutionIndex);
          return w.NumType.i32;
        case "_mainModuleRtt":
          final moduleRttType = translator.translateType(
              InterfaceType(translator.moduleRtt, Nullability.nonNullable));
          translator.constants.instantiateConstant(
              b, translator.types.rtt.mainModuleRtt, moduleRttType);
          return moduleRttType;
      }
    }

    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;
    Class? cls = target.enclosingClass;

    final intrinsic =
        StaticIntrinsic.fromProcedure(translator.coreTypes, target);

    if (intrinsic == null) return null;

    switch (intrinsic) {
      // extension {,Immutable}WasmArrayExt on {,Immutable}WasmArray<T>
      case StaticIntrinsic.wasmArrayIndex:
      case StaticIntrinsic.wasmArrayIndexSet:
      case StaticIntrinsic.wasmArrayCopy:
      case StaticIntrinsic.wasmArrayFill:
      case StaticIntrinsic.wasmArrayClone:
      case StaticIntrinsic.immutableWasmArrayIndex:
        final dartWasmArrayType = dartTypeOf(node.arguments.positional.first);
        final dartElementType =
            (dartWasmArrayType as InterfaceType).typeArguments.single;
        final w.ArrayType arrayType =
            (translator.translateType(dartWasmArrayType) as w.RefType).heapType
                as w.ArrayType;
        final w.FieldType fieldType = arrayType.elementType;
        final w.StorageType wasmType = fieldType.type;
        switch (intrinsic) {
          case StaticIntrinsic.wasmArrayIndex:
          case StaticIntrinsic.immutableWasmArrayIndex:
            final array = node.arguments.positional[0];
            final index = node.arguments.positional[1];
            codeGen.translateExpression(
                array, w.RefType.def(arrayType, nullable: false));
            codeGen.translateExpression(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 StaticIntrinsic.wasmArrayIndexSet:
            assert(fieldType.mutable);
            final array = node.arguments.positional[0];
            final index = node.arguments.positional[1];
            final value = node.arguments.positional[2];
            codeGen.translateExpression(
                array, w.RefType.def(arrayType, nullable: false));
            codeGen.translateExpression(index, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.translateExpression(value, typeOfExp(value));
            b.array_set(arrayType);
            return codeGen.voidMarker;
          case StaticIntrinsic.wasmArrayCopy:
            assert(fieldType.mutable);
            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.translateExpression(
                destArray, w.RefType.def(arrayType, nullable: false));
            codeGen.translateExpression(destOffset, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.translateExpression(
                sourceArray, w.RefType.def(arrayType, nullable: false));
            codeGen.translateExpression(sourceOffset, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.translateExpression(size, w.NumType.i64);
            b.i32_wrap_i64();
            b.array_copy(arrayType, arrayType);
            return codeGen.voidMarker;
          case StaticIntrinsic.wasmArrayFill:
            assert(fieldType.mutable);
            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.translateExpression(
                array, w.RefType.def(arrayType, nullable: false));
            codeGen.translateExpression(offset, w.NumType.i64);
            b.i32_wrap_i64();
            codeGen.translateExpression(
                value, translator.translateType(dartElementType));
            codeGen.translateExpression(size, w.NumType.i64);
            b.i32_wrap_i64();
            b.array_fill(arrayType);
            return codeGen.voidMarker;
          case StaticIntrinsic.wasmArrayClone:
            assert(fieldType.mutable);
            // Until `array.new_copy` we need a special case for empty arrays.
            // https://github.com/WebAssembly/gc/issues/367
            final sourceArray = node.arguments.positional[0];

            final sourceArrayRefType =
                w.RefType.def(arrayType, nullable: false);
            final sourceArrayLocal = b.addLocal(sourceArrayRefType);
            final newArrayLocal = b.addLocal(sourceArrayRefType);

            codeGen.translateExpression(sourceArray, sourceArrayRefType);
            b.local_tee(sourceArrayLocal);

            b.array_len();
            b.if_([], [sourceArrayRefType]);
            // Non-empty array. Create new one with the first element of the
            // source, then copy the rest.
            b.local_get(sourceArrayLocal);
            b.i32_const(0);
            b.array_get(arrayType);
            b.local_get(sourceArrayLocal);
            b.array_len();
            b.array_new(arrayType);
            b.local_tee(newArrayLocal); // copy dest
            b.i32_const(1); // copy dest offset
            b.local_get(sourceArrayLocal); // copy source
            b.i32_const(1); // copy source offset

            // copy size
            b.local_get(sourceArrayLocal);
            b.array_len();
            b.i32_const(1);
            b.i32_sub();

            b.array_copy(arrayType, arrayType);

            b.local_get(newArrayLocal);
            b.else_();
            // Empty array.
            b.array_new_fixed(arrayType, 0);
            b.end();

            return sourceArrayRefType;
          default:
            throw StateError('Unhandled WasmArray intrinsic: $intrinsic');
        }

      // extension {,Immutable}(I8|I16|I32|I64|F32|F64)ArrayExt on {,Immutable}WasmArray<...>
      case StaticIntrinsic.i8ArrayExtReadSigned:
      case StaticIntrinsic.immutableI8ArrayExtReadSigned:
      case StaticIntrinsic.i16ArrayExtReadSigned:
      case StaticIntrinsic.immutableI16ArrayExtReadSigned:
      case StaticIntrinsic.i32ArrayExtReadSigned:
      case StaticIntrinsic.immutableI32ArrayExtReadSigned:
      case StaticIntrinsic.i64ArrayExtRead:
      case StaticIntrinsic.immutableI64ArrayExtRead:
      case StaticIntrinsic.f32ArrayExtRead:
      case StaticIntrinsic.immutableF32ArrayExtRead:
      case StaticIntrinsic.f64ArrayExtRead:
      case StaticIntrinsic.immutableF64ArrayExtRead:
        return readIntArray(node, unsigned: false);
      case StaticIntrinsic.i8ArrayExtReadUnsigned:
      case StaticIntrinsic.immutableI8ArrayExtReadUnsigned:
      case StaticIntrinsic.i16ArrayExtReadUnsigned:
      case StaticIntrinsic.immutableI16ArrayExtReadUnsigned:
      case StaticIntrinsic.i32ArrayExtReadUnsigned:
      case StaticIntrinsic.immutableI32ArrayExtReadUnsigned:
        return readIntArray(node, unsigned: true);
      case StaticIntrinsic.i8ArrayExtWrite:
      case StaticIntrinsic.i16ArrayExtWrite:
      case StaticIntrinsic.i32ArrayExtWrite:
      case StaticIntrinsic.i64ArrayExtWrite:
      case StaticIntrinsic.f32ArrayExtWrite:
      case StaticIntrinsic.f64ArrayExtWrite:
        final dartWasmArrayType = dartTypeOf(node.arguments.positional.first);
        final w.ArrayType arrayType =
            (translator.translateType(dartWasmArrayType) as w.RefType).heapType
                as w.ArrayType;
        final w.FieldType fieldType = arrayType.elementType;
        final w.StorageType wasmType = fieldType.type;

        final outerExtend =
            wasmType.unpacked == w.NumType.i32 || wasmType == w.NumType.f32;
        assert(fieldType.mutable);
        final array = node.arguments.positional[0];
        final index = node.arguments.positional[1];
        final value = node.arguments.positional[2];
        codeGen.translateExpression(
            array, w.RefType.def(arrayType, nullable: false));
        codeGen.translateExpression(index, w.NumType.i64);
        b.i32_wrap_i64();
        codeGen.translateExpression(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;

      case StaticIntrinsic.identical:
        // We can use reference equality for `identical()` except if one of the
        // arguments can be a value type which would need to be compared by
        // value instead of by reference.
        //
        // NOTE: Even though `bool` is a value type, it has only two singleton
        // instances for `true` and `false` and we can therefore use reference
        // equality for it. Other value types may have different objects
        // containing the same value and need to be unboxed & compared by value.
        //
        // NOTE: We may get more value types in the future in Dart, for example
        // for SIMD types, see: https://github.com/dart-lang/sdk/issues/43255

        final first = node.arguments.positional[0];
        final second = node.arguments.positional[1];

        final firstType =
            translator.toMostSpecificInterfaceType(dartTypeOf(first));
        final secondType =
            translator.toMostSpecificInterfaceType(dartTypeOf(second));

        final intType = translator.boxedIntType;
        if (firstType == intType && secondType == intType) {
          codeGen.translateExpression(first, w.NumType.i64);
          codeGen.translateExpression(second, w.NumType.i64);
          b.i64_eq();
          return w.NumType.i32;
        }

        final doubleType = translator.boxedDoubleType;
        if (firstType == doubleType && secondType == doubleType) {
          codeGen.translateExpression(first, w.NumType.f64);
          b.i64_reinterpret_f64();
          codeGen.translateExpression(second, w.NumType.f64);
          b.i64_reinterpret_f64();
          b.i64_eq();
          return w.NumType.i32;
        }

        bool canBeValueType(DartType type) =>
            translator.typeEnvironment.isSubtypeOf(doubleType, type) ||
            translator.typeEnvironment.isSubtypeOf(intType, type);

        if (!canBeValueType(firstType) || !canBeValueType(secondType)) {
          final nullableEqRefType = w.RefType.eq(nullable: true);
          codeGen.translateExpression(first, nullableEqRefType);
          codeGen.translateExpression(second, nullableEqRefType);
          b.ref_eq();
          return w.NumType.i32;
        }

        return null;
      case StaticIntrinsic.isObjectClassId:
        final classId = node.arguments.positional.single;

        final objectClassId = (translator.classIdNumbering
                .classIds[translator.coreTypes.objectClass] as AbsoluteClassId)
            .value;

        codeGen.translateExpression(classId, w.NumType.i32);
        b.emitClassIdRangeCheck([Range(objectClassId, objectClassId)]);
        return w.NumType.i32;
      case StaticIntrinsic.isClosureClassId:
        final classId = node.arguments.positional.single;

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

        codeGen.translateExpression(classId, w.NumType.i32);
        b.emitClassIdRangeCheck(ranges);

        return w.NumType.i32;
      case StaticIntrinsic.isRecordClassId:
        final classId = node.arguments.positional.single;
        final ranges = translator.classIdNumbering
            .getConcreteClassIdRangeForMainModule(
                translator.coreTypes.recordClass);
        assert(ranges.length <= 1);

        if (translator.dynamicModuleSupportEnabled) {
          final submoduleRanges = translator.classIdNumbering
              .getConcreteClassIdRangeForDynamicSubmodule(
                  translator.coreTypes.recordClass);
          final classIdLocal = b.addLocal(w.NumType.i32);
          codeGen.translateExpression(classId, w.NumType.i32);
          b.local_tee(classIdLocal);
          b.local_get(classIdLocal);
          translator.dynamicModuleInfo!.callClassIdBranchBuiltIn(
              BuiltinUpdatableFunctions.recordId, b,
              skipSubmodule: submoduleRanges.isEmpty);
        } else {
          codeGen.translateExpression(classId, w.NumType.i32);
          b.emitClassIdRangeCheck(ranges);
        }
        return w.NumType.i32;

      // dart:_object_helper static functions.
      case StaticIntrinsic.getIdentityHashField:
        Expression arg = node.arguments.positional[0];
        w.ValueType objectType = translator.objectInfo.nonNullableType;
        codeGen.translateExpression(arg, objectType);
        b.struct_get(translator.objectInfo.struct, FieldIndex.identityHash);
        b.i64_extend_i32_u();
        return w.NumType.i64;
      case StaticIntrinsic.setIdentityHashField:
        Expression arg = node.arguments.positional[0];
        Expression hash = node.arguments.positional[1];
        w.ValueType objectType = translator.objectInfo.nonNullableType;
        codeGen.translateExpression(arg, objectType);
        codeGen.translateExpression(hash, w.NumType.i64);
        b.i32_wrap_i64();
        b.struct_set(translator.objectInfo.struct, FieldIndex.identityHash);
        return codeGen.voidMarker;

      // dart:_internal static functions
      case StaticIntrinsic.unsafeCast:
      case StaticIntrinsic.unsafeCastOpaque:
        Expression operand = node.arguments.positional.single;
        // Just evaluate the operand and let the context convert it to the
        // expected type.
        return codeGen.translateExpression(operand, typeOfExp(operand));
      case StaticIntrinsic.nativeEffect:
        // Ignore argument
        return translator.voidMarker;
      case StaticIntrinsic.floatToIntBits:
        codeGen.translateExpression(
            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 StaticIntrinsic.intBitsToFloat:
        codeGen.translateExpression(
            node.arguments.positional.single, w.NumType.i64);
        b.i32_wrap_i64();
        b.f32_reinterpret_i32();
        b.f64_promote_f32();
        return w.NumType.f64;
      case StaticIntrinsic.doubleToIntBits:
        codeGen.translateExpression(
            node.arguments.positional.single, w.NumType.f64);
        b.i64_reinterpret_f64();
        return w.NumType.i64;
      case StaticIntrinsic.intBitsToDouble:
        codeGen.translateExpression(
            node.arguments.positional.single, w.NumType.i64);
        b.f64_reinterpret_i64();
        return w.NumType.f64;
      case StaticIntrinsic.exportWasmFunction:
        const error =
            'The `dart:_internal:exportWasmFunction` expects its argument '
            'to be a tear-off of a `@pragma(\'wasm:weak-export\', ...)` '
            'annotated function';

        // Sanity check argument.
        final argument = node.arguments.positional.single;
        if (argument is! ConstantExpression) throw error;
        final constant = argument.constant;
        if (constant is! StaticTearOffConstant) throw error;
        final target = constant.target;
        if (translator.getPragma(target, 'wasm:weak-export', '') == null) {
          throw error;
        }

        // Ensure we compile the target function & export it.
        translator.functions.getFunction(target.reference);

        final topType = translator.topType;
        codeGen.translateExpression(NullLiteral(), topType);
        return topType;
      case StaticIntrinsic.getID:
        final type = translator.topTypeNonNullable;
        codeGen.translateExpression(node.arguments.positional.single, type);
        b.loadClassId(translator, type);
        return w.NumType.i32;

      // dart:ffi static functions
      case StaticIntrinsic.loadInt8:
      case StaticIntrinsic.loadUint8:
      case StaticIntrinsic.loadInt16:
      case StaticIntrinsic.loadUint16:
      case StaticIntrinsic.loadInt32:
      case StaticIntrinsic.loadUint32:
      case StaticIntrinsic.loadInt64:
      case StaticIntrinsic.loadUint64:
      case StaticIntrinsic.loadFloat:
      case StaticIntrinsic.loadFloatUnaligned:
      case StaticIntrinsic.loadDouble:
      case StaticIntrinsic.loadDoubleUnaligned:
      case StaticIntrinsic.storeInt8:
      case StaticIntrinsic.storeUint8:
      case StaticIntrinsic.storeInt16:
      case StaticIntrinsic.storeUint16:
      case StaticIntrinsic.storeInt32:
      case StaticIntrinsic.storeUint32:
      case StaticIntrinsic.storeInt64:
      case StaticIntrinsic.storeUint64:
      case StaticIntrinsic.storeFloat:
      case StaticIntrinsic.storeFloatUnaligned:
      case StaticIntrinsic.storeDouble:
      case StaticIntrinsic.storeDoubleUnaligned:
        Expression pointerArg = node.arguments.positional[0];
        Expression offsetArg = node.arguments.positional[1];
        final ffiPointerDartType =
            InterfaceType(translator.ffiPointerClass, Nullability.nonNullable);
        final ffiPointerWasmType =
            translator.translateType(ffiPointerDartType) as w.RefType;
        codeGen.translateExpression(pointerArg, ffiPointerWasmType);
        final ffiPointerStruct = ffiPointerWasmType.heapType as w.StructType;
        b.struct_get(ffiPointerStruct, FieldIndex.ffiPointerAddress);

        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.translateExpression(offsetArg, w.NumType.i64);
          b.i32_wrap_i64();
          b.i32_add();
          offset = 0;
        }
        switch (intrinsic) {
          case StaticIntrinsic.loadInt8:
            b.i64_load8_s(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadUint8:
            b.i64_load8_u(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadInt16:
            b.i64_load16_s(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadUint16:
            b.i64_load16_u(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadInt32:
            b.i64_load32_s(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadUint32:
            b.i64_load32_u(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadInt64:
          case StaticIntrinsic.loadUint64:
            b.i64_load(translator.ffiMemory, offset);
            return w.NumType.i64;
          case StaticIntrinsic.loadFloat:
            b.f32_load(translator.ffiMemory, offset);
            b.f64_promote_f32();
            return w.NumType.f64;
          case StaticIntrinsic.loadFloatUnaligned:
            b.f32_load(translator.ffiMemory, offset, 0);
            b.f64_promote_f32();
            return w.NumType.f64;
          case StaticIntrinsic.loadDouble:
            b.f64_load(translator.ffiMemory, offset);
            return w.NumType.f64;
          case StaticIntrinsic.loadDoubleUnaligned:
            b.f64_load(translator.ffiMemory, offset, 0);
            return w.NumType.f64;
          case StaticIntrinsic.storeInt8:
          case StaticIntrinsic.storeUint8:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.i64);
            b.i64_store8(translator.ffiMemory, offset);
            return translator.voidMarker;
          case StaticIntrinsic.storeInt16:
          case StaticIntrinsic.storeUint16:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.i64);
            b.i64_store16(translator.ffiMemory, offset);
            return translator.voidMarker;
          case StaticIntrinsic.storeInt32:
          case StaticIntrinsic.storeUint32:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.i64);
            b.i64_store32(translator.ffiMemory, offset);
            return translator.voidMarker;
          case StaticIntrinsic.storeInt64:
          case StaticIntrinsic.storeUint64:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.i64);
            b.i64_store(translator.ffiMemory, offset);
            return translator.voidMarker;
          case StaticIntrinsic.storeFloat:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.f64);
            b.f32_demote_f64();
            b.f32_store(translator.ffiMemory, offset);
            return translator.voidMarker;
          case StaticIntrinsic.storeFloatUnaligned:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.f64);
            b.f32_demote_f64();
            b.f32_store(translator.ffiMemory, offset, 0);
            return translator.voidMarker;
          case StaticIntrinsic.storeDouble:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.f64);
            b.f64_store(translator.ffiMemory, offset);
            return translator.voidMarker;
          case StaticIntrinsic.storeDoubleUnaligned:
            codeGen.translateExpression(
                node.arguments.positional[2], w.NumType.f64);
            b.f64_store(translator.ffiMemory, offset, 0);
            return translator.voidMarker;
          default:
            throw StateError('Unhandled ffi intrinsic: $intrinsic');
        }

      // WasmArray constructors
      case StaticIntrinsic.wasmArrayNew:
      case StaticIntrinsic.wasmArrayFilled:
      case StaticIntrinsic.immutableWasmArrayNew:
      case StaticIntrinsic.immutableWasmArrayFilled:
        final dartWasmArrayType =
            InterfaceType(cls!, Nullability.nonNullable, node.arguments.types);
        final dartElementType = node.arguments.types.single;
        final w.ArrayType arrayType =
            (translator.translateType(dartWasmArrayType) as w.RefType).heapType
                as w.ArrayType;

        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.translateExpression(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 = b.addLocal(w.NumType.i32);
            b.local_set(lengthTemp);
            codeGen.translateExpression(
                initialValue, arrayType.elementType.type.unpacked);
            b.local_get(lengthTemp);
            b.array_new(arrayType);
          }
        }
        return w.RefType.def(arrayType, nullable: false);

      // (WasmFuncRef|WasmFunction).fromRef constructors
      case StaticIntrinsic.wasmFunctionFromFuncRef:
        Expression ref = node.arguments.positional[0];
        w.RefType resultType = typeOfExp(node) as w.RefType;
        w.Label succeed = b.block(const [], [resultType]);
        codeGen.translateExpression(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;
      case StaticIntrinsic.wasmFunctionFromFunction:
        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);
        return translator.globals
            .readGlobal(b, translator.makeFunctionRef(wasmFunction));

      // Wasm(AnyRef|FuncRef|EqRef|StructRef|I32|I64|F32|F64) constructors
      case StaticIntrinsic.wasmI32FromInt:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i64);
        b.i32_wrap_i64();
        return w.NumType.i32;
      case StaticIntrinsic.wasmI32Int8FromInt:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i64);
        b.i32_wrap_i64();
        b.i32_extend8_s();
        return w.NumType.i32;
      case StaticIntrinsic.wasmI32Uint8FromInt:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i64);
        b.i32_wrap_i64();
        b.i32_const(0xFF);
        b.i32_and();
        return w.NumType.i32;
      case StaticIntrinsic.wasmI32Int16FromInt:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i64);
        b.i32_wrap_i64();
        b.i32_extend16_s();
        return w.NumType.i32;
      case StaticIntrinsic.wasmI32Uint16FromInt:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i64);
        b.i32_wrap_i64();
        b.i32_const(0xFFFF);
        b.i32_and();
        return w.NumType.i32;
      case StaticIntrinsic.wasmI32FromBool:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i32);
        return w.NumType.i32;
      case StaticIntrinsic.wasmI64FromInt:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i64);
        return w.NumType.i64;
      case StaticIntrinsic.wasmF32FromDouble:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.f64);
        b.f32_demote_f64();
        return w.NumType.f32;
      case StaticIntrinsic.wasmF64FromDouble:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.f64);
        return w.NumType.f64;
      case StaticIntrinsic.wasmAnyRefFromObject:
      case StaticIntrinsic.wasmFuncRefFromWasmFunction:
      case StaticIntrinsic.wasmEqRefFromObject:
      case StaticIntrinsic.wasmStructRefFromObject:
        Expression value = node.arguments.positional[0];
        w.StorageType targetType = translator.builtinTypes[cls]!;
        w.RefType valueType = targetType as w.RefType;
        codeGen.translateExpression(value, valueType);
        return valueType;
      case StaticIntrinsic.externalizeNonNullable:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.any(nullable: false));
        b.extern_convert_any();
        return w.RefType.extern(nullable: false);
      case StaticIntrinsic.externalizeNullable:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.any(nullable: true));
        b.extern_convert_any();
        return w.RefType.extern(nullable: true);
      case StaticIntrinsic.internalizeNonNullable:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.extern(nullable: false));
        b.any_convert_extern();
        return w.RefType.any(nullable: false);
      case StaticIntrinsic.internalizeNullable:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.extern(nullable: true));
        b.any_convert_extern();
        return w.RefType.any(nullable: true);
      case StaticIntrinsic.wasmExternRefIsNull:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.extern(nullable: true));
        b.ref_is_null();
        return w.NumType.i32;

      // dart:_wasm static functions
      case StaticIntrinsic.isSubClassOf:
        final baseClass =
            (node.arguments.types.single as InterfaceType).classNode;
        final ranges =
            translator.classIdNumbering.getConcreteSubclassRanges(baseClass);

        final object = node.arguments.positional.single;
        codeGen.translateExpression(object, translator.topTypeNonNullable);
        b.loadClassId(translator, translator.topTypeNonNullable);
        b.emitClassIdRangeCheck(ranges);
        return w.NumType.i32;

      case StaticIntrinsic.wasmI31RefNew:
        Expression value = node.arguments.positional[0];
        codeGen.translateExpression(value, w.NumType.i32);
        b.i31_new();
        return w.RefType.i31(nullable: false);

      case StaticIntrinsic.wasmI31RefExtensionsExternalize:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.i31(nullable: false));
        b.extern_convert_any();
        return w.RefType.extern(nullable: false);

      case StaticIntrinsic.wasmI31RefExtensionsGetS:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.i31(nullable: false));
        b.i31_get_s();
        return w.NumType.i32;

      case StaticIntrinsic.wasmI31RefExtensionsGetU:
        final value = node.arguments.positional.single;
        codeGen.translateExpression(value, w.RefType.i31(nullable: false));
        b.i31_get_u();
        return w.NumType.i32;
    }
  }

  /// 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 ||
            klass == translator.immutableWasmArrayClass) &&
        name == "literal") {
      final dartWasmArrayType = InterfaceType(node.target.enclosingClass,
          Nullability.nonNullable, node.arguments.types);
      final w.ArrayType arrayType =
          (translator.translateType(dartWasmArrayType) as w.RefType).heapType
              as w.ArrayType;

      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.translateExpression(element, elementType);
      }
      b.array_new_fixed(arrayType, elements.length);
      return w.RefType.def(arrayType, nullable: false);
    }

    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 = b.addLocal(receiverType);
      codeGen.translateExpression(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.translateExpression(
            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(b.moduleBuilder, 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 = b.addLocal(w.NumType.i32);
      codeGen.translateExpression(
          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.translateExpression(
            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.FunctionType functionType,
      List<w.Local> paramLocals, w.Label? returnLabel) {
    Member member = target.asMember;
    if (member is! Procedure) return false;
    final intrinsic =
        MemberIntrinsic.fromProcedure(translator.coreTypes, member);
    if (intrinsic == null) return false;

    switch (intrinsic) {
      case MemberIntrinsic.objectEquals:
        b.local_get(paramLocals[0]);
        b.local_get(paramLocals[1]);
        b.ref_eq();

      case MemberIntrinsic.objectRuntimeType:
        // 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);

      // identical
      case MemberIntrinsic.identical:
        w.Local first = paramLocals[0];
        w.Local second = paramLocals[1];
        ClassInfo intInfo = translator.classInfo[translator.boxedIntClass]!;
        ClassInfo doubleInfo =
            translator.classInfo[translator.boxedDoubleClass]!;
        w.Local cid = b.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.loadClassId(translator, translator.topTypeNonNullable);
        b.local_tee(cid);
        b.local_get(second);
        b.br_on_null(fail);
        b.loadClassId(translator, translator.topTypeNonNullable);
        b.i32_ne();
        b.br_if(fail);

        // Cannot be equal `bool`s as we have unique singleton objects for `true`
        // and `false`. If they were equal bools we would have triggered the
        // reference equality above.

        // Both int?
        b.local_get(cid);
        b.i32_const((intInfo.classId as AbsoluteClassId).value);
        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 as AbsoluteClassId).value);
        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);

      // _Closure._getClosureRuntimeType
      case MemberIntrinsic.closureRuntimeType:
        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);

      case MemberIntrinsic.identityHashCode:
        final w.Local arg = paramLocals[0];
        final w.Local nonNullArg = b.addLocal(translator.topTypeNonNullable);
        final List<int> classIds = translator.valueClasses.keys
            .map((cls) =>
                (translator.classInfo[cls]!.classId as AbsoluteClassId).value)
            .toList()
          ..sort();

        // If the argument is `null`, return the hash code of `null`.
        final w.Label notNull =
            b.block(const [], [translator.topTypeNonNullable]);
        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.loadClassId(translator, translator.topTypeNonNullable);
        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);

      // _typeArguments
      case MemberIntrinsic.typeArguments:
        Class cls = member.enclosingClass!;
        ClassInfo classInfo = translator.classInfo[cls]!;
        w.ArrayType arrayType =
            (functionType.outputs.single as w.RefType).heapType as w.ArrayType;
        w.Local object = paramLocals[0];
        w.Local preciseObject =
            codeGen.addLocal(classInfo.nonNullableType, name: "this");
        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);

      // int members
      case MemberIntrinsic.intAdd:
      case MemberIntrinsic.intSub:
      case MemberIntrinsic.intMul:
      case MemberIntrinsic.intAnd:
      case MemberIntrinsic.intOr:
      case MemberIntrinsic.intXor:
      case MemberIntrinsic.intLt:
      case MemberIntrinsic.intGt:
      case MemberIntrinsic.intGe:
      case MemberIntrinsic.intLe:
      case MemberIntrinsic.intNeg:
      case MemberIntrinsic.intInv:
      case MemberIntrinsic.intToDouble:
        final functionNode = member.function;
        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 = functionType.inputs.single;
            w.ValueType outputType = functionType.outputs.single;
            b.local_get(paramLocals[0]);
            translator.convertType(b, inputType, intType);
            code(codeGen);
            translator.convertType(b, resultType, outputType);
            return true;
          }
        } else if (functionNode.requiredParameterCount == 1) {
          CodeGenCallback? code = _binaryOperatorMap[intType]![intType]![op];
          if (code != null) {
            w.ValueType leftType = functionType.inputs[0];
            w.ValueType rightType = functionType.inputs[1];
            w.ValueType outputType = functionType.outputs.single;
            if (rightType == intType) {
              // int parameter
              b.local_get(paramLocals[0]);
              translator.convertType(b, leftType, intType);
              b.local_get(paramLocals[1]);
              code(codeGen);
              if (!isComparison(op)) {
                translator.convertType(b, intType, outputType);
              }
              return true;
            }
            // num parameter
            ClassInfo intInfo = translator.classInfo[translator.boxedIntClass]!;
            w.Label intArg = b.block(const [], [intInfo.nonNullableType]);
            b.local_get(paramLocals[1]);
            b.br_on_cast(intArg, paramLocals[1].type as w.RefType,
                intInfo.nonNullableType);
            // double argument
            b.drop();
            b.local_get(paramLocals[0]);
            translator.convertType(b, leftType, intType);
            b.f64_convert_i64_s();
            b.local_get(paramLocals[1]);
            translator.convertType(b, rightType, doubleType);
            // Inline double op
            CodeGenCallback doubleCode =
                _binaryOperatorMap[doubleType]![doubleType]![op]!;
            doubleCode(codeGen);
            if (!isComparison(op)) {
              translator.convertType(b, doubleType, outputType);
            }
            b.return_();
            b.end();
            // int argument
            translator.convertType(b, intInfo.nonNullableType, intType);
            w.Local rightTemp = b.addLocal(intType);
            b.local_set(rightTemp);
            b.local_get(paramLocals[0]);
            translator.convertType(b, leftType, intType);
            b.local_get(rightTemp);
            code(codeGen);
            if (!isComparison(op)) {
              translator.convertType(b, intType, outputType);
            }
            return true;
          }
        }

      // double unary members
      case MemberIntrinsic.doubleNeg:
      case MemberIntrinsic.doubleFloorToDouble:
      case MemberIntrinsic.doubleCeilToDouble:
      case MemberIntrinsic.doubleTruncateToDouble:
        final op = member.name.text;
        CodeGenCallback? code = _unaryOperatorMap[doubleType]![op]!;
        w.ValueType resultType = _unaryResultMap[op] ?? doubleType;
        w.ValueType inputType = functionType.inputs.single;
        w.ValueType outputType = functionType.outputs.single;
        b.local_get(paramLocals[0]);
        translator.convertType(b, inputType, doubleType);
        code(codeGen);
        translator.convertType(b, resultType, outputType);

      case MemberIntrinsic.isInstantiationClosure:
        assert(paramLocals.length == 1);
        b.local_get(paramLocals[0]); // ref _Closure
        b.emitInstantiationClosureCheck(translator);

      case MemberIntrinsic.instantiatedClosure:
        assert(paramLocals.length == 1);
        b.local_get(paramLocals[0]); // ref _Closure
        b.emitGetInstantiatedClosure(translator);

      case MemberIntrinsic.instantiationClosureTypeHash:
        assert(paramLocals.length == 1);

        // Instantiation context, to be passed to the hash function.
        b.local_get(paramLocals[0]); // ref _Closure
        b.ref_cast(w.RefType(translator.closureLayouter.closureBaseStruct,
            nullable: false));
        b.struct_get(translator.closureLayouter.closureBaseStruct,
            FieldIndex.closureContext);
        b.ref_cast(w.RefType(
            translator.closureLayouter.instantiationContextBaseStruct,
            nullable: false));

        // Hash function.
        b.local_get(paramLocals[0]); // ref _Closure
        b.emitGetInstantiatedClosure(translator);
        b.emitGetClosureVtable(translator);
        b.ref_cast(w.RefType.def(
            translator.closureLayouter.genericVtableBaseStruct,
            nullable: false));
        b.struct_get(
            translator.closureLayouter.genericVtableBaseStruct,
            translator
                .closureLayouter.vtableInstantiationTypeHashFunctionIndex);
        b.call_ref(translator
            .closureLayouter.instantiationClosureTypeHashFunctionType);

      case MemberIntrinsic.instantiationClosureTypeEquals:
        assert(paramLocals.length == 2);

        final w.StructType closureBaseStruct =
            translator.closureLayouter.closureBaseStruct;

        final w.RefType instantiationContextBase = w.RefType(
            translator.closureLayouter.instantiationContextBaseStruct,
            nullable: false);

        b.local_get(paramLocals[0]); // ref _Closure
        b.ref_cast(w.RefType(closureBaseStruct, nullable: false));
        b.struct_get(closureBaseStruct, FieldIndex.closureContext);
        b.ref_cast(instantiationContextBase);

        b.local_get(paramLocals[1]); // ref _Closure
        b.ref_cast(w.RefType(closureBaseStruct, nullable: false));
        b.struct_get(closureBaseStruct, FieldIndex.closureContext);
        b.ref_cast(instantiationContextBase);

        b.local_get(paramLocals[0]);
        b.emitGetInstantiatedClosure(translator);
        b.emitGetClosureVtable(translator);
        b.ref_cast(w.RefType.def(
            translator.closureLayouter.genericVtableBaseStruct,
            nullable: false));

        final vtableIndex = translator
            .closureLayouter.vtableInstantiationTypeComparisonFunctionIndex;
        b.struct_get(
            translator.closureLayouter.genericVtableBaseStruct, vtableIndex);
        b.call_ref(translator
            .closureLayouter.instantiationClosureTypeComparisonFunctionType);

      case MemberIntrinsic.isInstanceTearOff:
        assert(paramLocals.length == 1);
        b.local_get(paramLocals[0]); // ref _Closure
        b.emitTearOffCheck(translator);

      case MemberIntrinsic.instanceTearOffReceiver:
        assert(paramLocals.length == 1);
        b.local_get(paramLocals[0]); // ref _Closure
        b.emitGetTearOffReceiver(translator);

      case MemberIntrinsic.vtable:
        assert(paramLocals.length == 1);
        b.local_get(paramLocals[0]); // ref _Closure
        b.emitGetClosureVtable(translator);

      case MemberIntrinsic.functionApply:
        assert(functionType.inputs.length == 3);

        final closureLocal = paramLocals[0]; // ref #ClosureBase
        final posArgsNullableLocal = paramLocals[1]; // ref null Object
        final namedArgsLocal = paramLocals[2]; // ref null Object

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

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

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

        b.else_();
        // List argument may be a custom list type, convert it to `WasmListBase`
        // with `WasmListBase.of`.
        translator.constants.instantiateConstant(
          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 array, to be passed to shape and type
        // checkers and the dynamic call entry.
        final namedArgsListLocal =
            b.addLocal(translator.nullableObjectArrayTypeRef);
        b.local_get(namedArgsLocal);
        b.local_get(closureLocal);
        codeGen.call(translator.namedParameterMapToArray.reference);
        b.local_set(namedArgsListLocal);

        final noSuchMethodBlock = b.block();

        generateDynamicClosureCallShapeAndTypeCheck(translator, b, closureLocal,
            typeArgsLocal, posArgsLocal, namedArgsListLocal, noSuchMethodBlock);
        if (translator.dynamicModuleSupportEnabled ||
            translator.closureLayouter.usesFunctionApplyWithNamedArguments) {
          generateDynamicClosureCallViaDynamicEntry(translator, b, closureLocal,
              typeArgsLocal, posArgsLocal, namedArgsListLocal);
        } else {
          if (compilerAssertsEnabled) {
            final good = b.block();
            b.local_get(namedArgsListLocal);
            b.array_len();
            b.i32_eqz();
            b.br_if(good);
            b.unreachable();
            b.end();
          }
          generateDynamicClosureCallViaPositionalArgs(
              translator, b, closureLocal, typeArgsLocal, posArgsLocal);
        }
        b.return_();

        b.end(); // noSuchMethodBlock

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

      // Error._throw
      case MemberIntrinsic.errorThrow:
        final objectLocal = paramLocals[0]; // ref #Top
        final stackTraceLocal = paramLocals[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 = b.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.getExceptionTag(b.moduleBuilder));

      case MemberIntrinsic.nullRef:
        b.ref_null(w.HeapType.noextern);
    }

    return true;
  }

  w.ValueType readIntArray(StaticInvocation node, {required bool unsigned}) {
    final dartWasmArrayType = dartTypeOf(node.arguments.positional.first);
    final w.ArrayType arrayType =
        (translator.translateType(dartWasmArrayType) as w.RefType).heapType
            as w.ArrayType;
    final w.FieldType fieldType = arrayType.elementType;
    final w.StorageType wasmType = fieldType.type;

    final innerExtend =
        wasmType == w.PackedType.i8 || wasmType == w.PackedType.i16;
    final outerExtend =
        wasmType.unpacked == w.NumType.i32 || wasmType == w.NumType.f32;
    final array = node.arguments.positional[0];
    final index = node.arguments.positional[1];
    codeGen.translateExpression(
        array, w.RefType.def(arrayType, nullable: false));
    codeGen.translateExpression(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;
  }
}

int? _extractIntValue(Expression expr) {
  if (expr is IntLiteral) {
    return expr.value;
  }

  if (expr is ConstantExpression) {
    final constant = expr.constant;
    if (constant is IntConstant) {
      return constant.value;
    }
  }

  return null;
}

double? _extractDoubleValue(Expression expr) {
  if (expr is DoubleLiteral) {
    return expr.value;
  }

  if (expr is ConstantExpression) {
    final constant = expr.constant;
    if (constant is DoubleConstant) {
      return constant.value;
    }
  }

  return null;
}
