// 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.module, 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.module, 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.module, 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,
            FieldIndex.vtableInstantiationTypeHashFunction);
        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));
        b.struct_get(translator.closureLayouter.genericVtableBaseStruct,
            FieldIndex.vtableInstantiationTypeComparisonFunction);

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

        generateDynamicFunctionCall(translator, b, closureLocal, typeArgsLocal,
            posArgsLocal, namedArgsListLocal, noSuchMethodBlock);
        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.module));

      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;
}
