// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:typed_data' show Uint8List;

import 'package:kernel/ast.dart' show TreeNode;

import 'dbc.dart';
import 'exceptions.dart' show ExceptionsTable;
import 'local_variable_table.dart' show LocalVariableTable;
import 'options.dart';
import 'source_positions.dart'
    show RecordedCoverageArray, RecordedCoverageType, SourcePositions;

class Label {
  final bool allowsBackwardJumps;
  List<int>? _jumps = <int>[];
  int offset = -1;

  Label({this.allowsBackwardJumps = false});

  bool get isBound => offset >= 0;

  int jumpOperand(int jumpOffset) {
    if (isBound) {
      if (offset <= jumpOffset && !allowsBackwardJumps) {
        throw 'Backward jump to this label is not allowed';
      }
      // Jump instruction takes a relative offset.
      return offset - jumpOffset;
    }
    _jumps!.add(jumpOffset);
    return 0;
  }

  List<int> bind(int offset) {
    assert(!isBound);
    this.offset = offset;
    final jumps = _jumps!;
    _jumps = null;
    return jumps;
  }
}

class BytecodeAssembler {
  static const int kByteMask = 0xFF;
  static const int kUint32Mask = 0xFFFFFFFF;
  static const int kMinInt8 = -0x80;
  static const int kMaxInt8 = 0x7F;
  static const int kMinInt24 = -0x800000;
  static const int kMaxInt24 = 0x7FFFFF;
  static const int kMinInt32 = -0x80000000;
  static const int kMaxInt32 = 0x7FFFFFFF;

  static const int kInitialCapacity = 32;

  int _length = 0;
  Uint8List _buffer = new Uint8List(kInitialCapacity);

  final ExceptionsTable exceptionsTable = new ExceptionsTable();
  final LocalVariableTable localVariableTable = new LocalVariableTable();
  final SourcePositions sourcePositions = new SourcePositions();
  final RecordedCoverageArray recordedCoverageArray =
      new RecordedCoverageArray();
  final bool _emitSourcePositions;
  final bool _recordCoverage;
  bool isUnreachable = false;
  int currentSourcePosition = TreeNode.noOffset;
  int currentSourcePositionFlags = 0;

  BytecodeAssembler(BytecodeOptions options)
    : _emitSourcePositions = options.emitSourcePositions,
      _recordCoverage = options.recordCoverage;

  int get offset => _length;

  Uint8List get bytecode => new Uint8List.view(_buffer.buffer, 0, _length);

  void bind(Label label) {
    final List<int> jumps = label.bind(offset);
    for (int jumpOffset in jumps) {
      _patchJump(jumpOffset, label.jumpOperand(jumpOffset));
    }
    if (jumps.isNotEmpty || label.allowsBackwardJumps) {
      isUnreachable = false;
    }
  }

  @pragma('vm:prefer-inline')
  void _emitSourcePosition() {
    final position = currentSourcePosition == TreeNode.noOffset
        ? SourcePositions.noSourcePosition
        : currentSourcePosition;
    if (_emitSourcePositions && !isUnreachable) {
      bool added = sourcePositions.add(
        offset,
        position,
        currentSourcePositionFlags,
      );
      if (!added) {
        // There's already an entry for the current PC, so emit a Nop instruction
        // to provide a new pc offset for the requested source position.
        emitNop();
        added = sourcePositions.add(
          offset,
          position,
          currentSourcePositionFlags,
        );
        assert(added);
      }
    }
  }

  @pragma('vm:prefer-inline')
  void emitSourcePosition() {
    if (currentSourcePosition != TreeNode.noOffset) {
      _emitSourcePosition();
    }
  }

  // TreeNode.noOffset (-1) source position on calls is used to mark synthetic
  // calls without corresponding source position. Debugger uses the absence of
  // source position to distinguish these calls and avoid stopping at them
  // while single stepping.
  @pragma('vm:prefer-inline')
  void emitSourcePositionForCall() => _emitSourcePosition();

  void _grow() {
    final newSize = _buffer.length << 1;
    final newBuffer = new Uint8List(newSize);
    newBuffer.setRange(0, _buffer.length, _buffer);
    _buffer = newBuffer;
  }

  void _growAndEmitBytes(
    int b0, [
    int? b1,
    int? b2,
    int? b3,
    int? b4,
    int? b5,
  ]) {
    _grow();
    assert(_length + 6 < _buffer.length);
    _buffer[_length] = b0;
    ++_length;
    if (b1 != null) {
      _buffer[_length] = b1;
      ++_length;
      if (b2 != null) {
        _buffer[_length] = b2;
        ++_length;
        if (b3 != null) {
          _buffer[_length] = b3;
          ++_length;
          if (b4 != null) {
            _buffer[_length] = b4;
            ++_length;
            if (b5 != null) {
              _buffer[_length] = b5;
              ++_length;
            }
          }
        }
      }
    }
  }

  @pragma('vm:prefer-inline')
  void _emitByte(int abyte) {
    assert(_isUint8(abyte));
    if (_length < _buffer.length) {
      _buffer[_length] = abyte;
      ++_length;
    } else {
      _growAndEmitBytes(abyte);
    }
  }

  @pragma('vm:prefer-inline')
  void _emitBytes2(int b0, int b1) {
    assert(_isUint8(b0) && _isUint8(b1));
    if (_length + 1 < _buffer.length) {
      _buffer[_length] = b0;
      _buffer[_length + 1] = b1;
      _length += 2;
    } else {
      _growAndEmitBytes(b0, b1);
    }
  }

  @pragma('vm:prefer-inline')
  void _emitBytes3(int b0, int b1, int b2) {
    assert(_isUint8(b0) && _isUint8(b1) && _isUint8(b2));
    if (_length + 2 < _buffer.length) {
      _buffer[_length] = b0;
      _buffer[_length + 1] = b1;
      _buffer[_length + 2] = b2;
      _length += 3;
    } else {
      _growAndEmitBytes(b0, b1, b2);
    }
  }

  @pragma('vm:prefer-inline')
  void _emitBytes4(int b0, int b1, int b2, int b3) {
    assert(_isUint8(b0) && _isUint8(b1) && _isUint8(b2) && _isUint8(b3));
    if (_length + 3 < _buffer.length) {
      _buffer[_length] = b0;
      _buffer[_length + 1] = b1;
      _buffer[_length + 2] = b2;
      _buffer[_length + 3] = b3;
      _length += 4;
    } else {
      _growAndEmitBytes(b0, b1, b2, b3);
    }
  }

  void _emitBytes5(int b0, int b1, int b2, int b3, int b4) {
    assert(
      _isUint8(b0) &&
          _isUint8(b1) &&
          _isUint8(b2) &&
          _isUint8(b3) &&
          _isUint8(b4),
    );
    if (_length + 4 < _buffer.length) {
      _buffer[_length] = b0;
      _buffer[_length + 1] = b1;
      _buffer[_length + 2] = b2;
      _buffer[_length + 3] = b3;
      _buffer[_length + 4] = b4;
      _length += 5;
    } else {
      _growAndEmitBytes(b0, b1, b2, b3, b4);
    }
  }

  void _emitBytes6(int b0, int b1, int b2, int b3, int b4, int b5) {
    assert(
      _isUint8(b0) &&
          _isUint8(b1) &&
          _isUint8(b2) &&
          _isUint8(b3) &&
          _isUint8(b4) &&
          _isUint8(b5),
    );
    if (_length + 5 < _buffer.length) {
      _buffer[_length] = b0;
      _buffer[_length + 1] = b1;
      _buffer[_length + 2] = b2;
      _buffer[_length + 3] = b3;
      _buffer[_length + 4] = b4;
      _buffer[_length + 5] = b5;
      _length += 6;
    } else {
      _growAndEmitBytes(b0, b1, b2, b3, b4, b5);
    }
  }

  int _byteAt(int pos) {
    return _buffer[pos];
  }

  void _setByteAt(int pos, int value) {
    assert(_isUint8(value));
    _buffer[pos] = value;
  }

  @pragma('vm:prefer-inline')
  int _byte0(int v) => v & kByteMask;

  @pragma('vm:prefer-inline')
  int _byte1(int v) => (v >> 8) & kByteMask;

  @pragma('vm:prefer-inline')
  int _byte2(int v) => (v >> 16) & kByteMask;

  @pragma('vm:prefer-inline')
  int _byte3(int v) => (v >> 24) & kByteMask;

  @pragma('vm:prefer-inline')
  bool _isInt8(int v) => (kMinInt8 <= v) && (v <= kMaxInt8);

  @pragma('vm:prefer-inline')
  bool _isInt24(int v) => (kMinInt24 <= v) && (v <= kMaxInt24);

  @pragma('vm:prefer-inline')
  bool _isInt32(int v) => (kMinInt32 <= v) && (v <= kMaxInt32);

  @pragma('vm:prefer-inline')
  bool _isUint8(int v) => (v & kByteMask) == v;

  @pragma('vm:prefer-inline')
  bool _isUint32(int v) => (v & kUint32Mask) == v;

  @pragma('vm:prefer-inline')
  void _emitInstruction0(Opcode opcode) {
    if (isUnreachable) {
      return;
    }
    _emitByte(opcode.index);
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionA(Opcode opcode, int ra) {
    if (isUnreachable) {
      return;
    }
    _emitBytes2(opcode.index, ra);
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionD(Opcode opcode, int rd) {
    if (isUnreachable) {
      return;
    }
    if (_isUint8(rd)) {
      _emitBytes2(opcode.index, rd);
    } else {
      assert(_isUint32(rd));
      _emitBytes5(
        opcode.index + kWideModifier,
        _byte0(rd),
        _byte1(rd),
        _byte2(rd),
        _byte3(rd),
      );
    }
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionX(Opcode opcode, int rx) {
    if (isUnreachable) {
      return;
    }
    if (_isInt8(rx)) {
      _emitBytes2(opcode.index, rx & kByteMask);
    } else {
      assert(_isInt32(rx));
      _emitBytes5(
        opcode.index + kWideModifier,
        _byte0(rx),
        _byte1(rx),
        _byte2(rx),
        _byte3(rx),
      );
    }
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionAE(Opcode opcode, int ra, int re) {
    if (isUnreachable) {
      return;
    }
    if (_isUint8(re)) {
      _emitBytes3(opcode.index, ra, re);
    } else {
      assert(_isUint32(re));
      _emitBytes6(
        opcode.index + kWideModifier,
        ra,
        _byte0(re),
        _byte1(re),
        _byte2(re),
        _byte3(re),
      );
    }
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionAY(Opcode opcode, int ra, int ry) {
    if (isUnreachable) {
      return;
    }
    if (_isInt8(ry)) {
      _emitBytes3(opcode.index, ra, ry & kByteMask);
    } else {
      assert(_isInt32(ry));
      _emitBytes6(
        opcode.index + kWideModifier,
        ra,
        _byte0(ry),
        _byte1(ry),
        _byte2(ry),
        _byte3(ry),
      );
    }
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionDF(Opcode opcode, int rd, int rf) {
    if (isUnreachable) {
      return;
    }
    if (_isUint8(rd)) {
      _emitBytes3(opcode.index, rd, rf);
    } else {
      assert(_isUint32(rd));
      _emitBytes6(
        opcode.index + kWideModifier,
        _byte0(rd),
        _byte1(rd),
        _byte2(rd),
        _byte3(rd),
        rf,
      );
    }
  }

  @pragma('vm:prefer-inline')
  void _emitInstructionABC(Opcode opcode, int ra, int rb, int rc) {
    if (isUnreachable) {
      return;
    }
    _emitBytes4(opcode.index, ra, rb, rc);
  }

  @pragma('vm:prefer-inline')
  void emitSpecializedBytecode(Opcode opcode) {
    assert(BytecodeFormats[opcode]!.encoding == Encoding.k0);
    emitSourcePosition();
    _emitInstruction0(opcode);
  }

  @pragma('vm:prefer-inline')
  void _emitJumpInstruction(Opcode opcode, Label label) {
    assert(isJump(opcode));
    if (isUnreachable) {
      return;
    }
    final int target = label.jumpOperand(offset);
    // Use compact representation only for backwards jumps.
    // TODO(alexmarkov): generate compact forward jumps as well.
    if (label.isBound && _isInt8(target)) {
      _emitBytes2(opcode.index, target & kByteMask);
    } else {
      assert(_isInt24(target));
      _emitBytes4(
        opcode.index + kWideModifier,
        _byte0(target),
        _byte1(target),
        _byte2(target),
      );
    }
  }

  void _patchJump(int pos, int rt) {
    final Opcode opcode = Opcode.values[_byteAt(pos) - kWideModifier];
    assert(hasWideVariant(opcode));
    assert(isJump(opcode));
    assert(_isInt24(rt));
    _setByteAt(pos + 1, _byte0(rt));
    _setByteAt(pos + 2, _byte1(rt));
    _setByteAt(pos + 3, _byte2(rt));
  }

  void emitTrap() {
    _emitInstruction0(Opcode.kTrap);
    isUnreachable = true;
  }

  @pragma('vm:prefer-inline')
  void emitDrop1() {
    _emitInstruction0(Opcode.kDrop1);
  }

  @pragma('vm:prefer-inline')
  void emitJump(Label label) {
    _emitJumpInstruction(Opcode.kJump, label);
    isUnreachable = true;
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfNoAsserts(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfNoAsserts, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfNotZeroTypeArgs(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfNotZeroTypeArgs, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfEqStrict(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfEqStrict, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfNeStrict(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfNeStrict, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfTrue(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfTrue, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfFalse(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfFalse, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfNull(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfNull, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfNotNull(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfNotNull, label);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfUnchecked(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfUnchecked, label);
  }

  @pragma('vm:prefer-inline')
  void emitSuspend(Label label) {
    _emitJumpInstruction(Opcode.kSuspend, label);
  }

  @pragma('vm:prefer-inline')
  void emitReturnTOS() {
    emitSourcePosition();
    _emitInstruction0(Opcode.kReturnTOS);
    isUnreachable = true;
  }

  @pragma('vm:prefer-inline')
  void emitPush(int rx) {
    _emitInstructionX(Opcode.kPush, rx);
  }

  @pragma('vm:prefer-inline')
  void emitDup() {
    _emitInstruction0(Opcode.kDup);
  }

  @pragma('vm:prefer-inline')
  void emitLoadConstant(int ra, int re) {
    _emitInstructionAE(Opcode.kLoadConstant, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitPushConstant(int rd) {
    _emitInstructionD(Opcode.kPushConstant, rd);
  }

  @pragma('vm:prefer-inline')
  void emitPushNull() {
    _emitInstruction0(Opcode.kPushNull);
  }

  @pragma('vm:prefer-inline')
  void emitPushTrue() {
    _emitInstruction0(Opcode.kPushTrue);
  }

  @pragma('vm:prefer-inline')
  void emitPushFalse() {
    _emitInstruction0(Opcode.kPushFalse);
  }

  @pragma('vm:prefer-inline')
  void emitPushInt(int rx) {
    _emitInstructionX(Opcode.kPushInt, rx);
  }

  @pragma('vm:prefer-inline')
  void emitStoreLocal(int rx) {
    _emitInstructionX(Opcode.kStoreLocal, rx);
  }

  @pragma('vm:prefer-inline')
  void emitPopLocal(int rx) {
    _emitInstructionX(Opcode.kPopLocal, rx);
  }

  @pragma('vm:prefer-inline')
  void emitDirectCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kDirectCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitUncheckedDirectCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kUncheckedDirectCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitInterfaceCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kInterfaceCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitInstantiatedInterfaceCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kInstantiatedInterfaceCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitUncheckedClosureCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kUncheckedClosureCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitUncheckedInterfaceCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kUncheckedInterfaceCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitDynamicCall(int rd, int rf) {
    emitSourcePositionForCall();
    _emitInstructionDF(Opcode.kDynamicCall, rd, rf);
  }

  @pragma('vm:prefer-inline')
  void emitExternalCall(int rd) {
    _emitInstructionD(Opcode.kExternalCall, rd);
  }

  @pragma('vm:prefer-inline')
  void emitFfiCall(int rd) {
    _emitInstructionD(Opcode.kFfiCall, rd);
  }

  @pragma('vm:prefer-inline')
  void emitResolveNativeFunction(int rd) {
    _emitInstructionD(Opcode.kResolveNativeFunction, rd);
  }

  @pragma('vm:prefer-inline')
  void emitLoadStatic(int rd) {
    _emitInstructionD(Opcode.kLoadStatic, rd);
  }

  @pragma('vm:prefer-inline')
  void emitStoreStaticTOS(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kStoreStaticTOS, rd);
  }

  @pragma('vm:prefer-inline')
  void emitCreateArrayTOS() {
    _emitInstruction0(Opcode.kCreateArrayTOS);
  }

  @pragma('vm:prefer-inline')
  void emitAllocate(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kAllocate, rd);
  }

  @pragma('vm:prefer-inline')
  void emitAllocateT() {
    emitSourcePosition();
    _emitInstruction0(Opcode.kAllocateT);
  }

  @pragma('vm:prefer-inline')
  void emitStoreIndexedTOS() {
    _emitInstruction0(Opcode.kStoreIndexedTOS);
  }

  @pragma('vm:prefer-inline')
  void emitStoreFieldTOS(int rd) {
    _emitInstructionD(Opcode.kStoreFieldTOS, rd);
  }

  @pragma('vm:prefer-inline')
  void emitStoreContextParent() {
    _emitInstruction0(Opcode.kStoreContextParent);
  }

  @pragma('vm:prefer-inline')
  void emitStoreContextVar(int ra, int re) {
    _emitInstructionAE(Opcode.kStoreContextVar, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitLoadFieldTOS(int rd) {
    _emitInstructionD(Opcode.kLoadFieldTOS, rd);
  }

  @pragma('vm:prefer-inline')
  void emitLoadTypeArgumentsField(int rd) {
    _emitInstructionD(Opcode.kLoadTypeArgumentsField, rd);
  }

  @pragma('vm:prefer-inline')
  void emitLoadContextParent() {
    _emitInstruction0(Opcode.kLoadContextParent);
  }

  @pragma('vm:prefer-inline')
  void emitLoadContextVar(int ra, int re) {
    _emitInstructionAE(Opcode.kLoadContextVar, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitBooleanNegateTOS() {
    _emitInstruction0(Opcode.kBooleanNegateTOS);
  }

  @pragma('vm:prefer-inline')
  void emitThrow(int ra) {
    emitSourcePosition();
    _emitInstructionA(Opcode.kThrow, ra);
    isUnreachable = true;
  }

  @pragma('vm:prefer-inline')
  void emitEntry(int rd) {
    _emitInstructionD(Opcode.kEntry, rd);
  }

  @pragma('vm:prefer-inline')
  void emitFrame(int rd) {
    _emitInstructionD(Opcode.kFrame, rd);
  }

  @pragma('vm:prefer-inline')
  void emitSetFrame(int ra) {
    _emitInstructionA(Opcode.kSetFrame, ra);
  }

  @pragma('vm:prefer-inline')
  void emitAllocateContext(int ra, int re) {
    _emitInstructionAE(Opcode.kAllocateContext, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitCloneContext(int ra, int re) {
    _emitInstructionAE(Opcode.kCloneContext, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitMoveSpecial(SpecialIndex ra, int ry) {
    _emitInstructionAY(Opcode.kMoveSpecial, ra.index, ry);
  }

  @pragma('vm:prefer-inline')
  void emitInstantiateType(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kInstantiateType, rd);
  }

  @pragma('vm:prefer-inline')
  void emitInstantiateTypeArgumentsTOS(int ra, int re) {
    emitSourcePosition();
    _emitInstructionAE(Opcode.kInstantiateTypeArgumentsTOS, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitAssertAssignable(int ra, int re) {
    emitSourcePosition();
    _emitInstructionAE(Opcode.kAssertAssignable, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitAssertSubtype() {
    emitSourcePosition();
    _emitInstruction0(Opcode.kAssertSubtype);
  }

  @pragma('vm:prefer-inline')
  void emitCheckStack(int ra) {
    emitSourcePosition();
    _emitInstructionA(Opcode.kCheckStack, ra);
  }

  // Nops are explicitly created by the bytecode generator in only one case
  // (calls to dart:developer::debugger). Otherwise, they are introduced by
  // the assembler in order to provide unique pc offsets for source positions.
  @pragma('vm:prefer-inline')
  void emitNop() {
    _emitInstruction0(Opcode.kNop);
  }

  @pragma('vm:prefer-inline')
  void emitCheckFunctionTypeArgs(int ra, int re) {
    emitSourcePosition();
    _emitInstructionAE(Opcode.kCheckFunctionTypeArgs, ra, re);
  }

  @pragma('vm:prefer-inline')
  void emitEntryOptional(int ra, int rb, int rc) {
    _emitInstructionABC(Opcode.kEntryOptional, ra, rb, rc);
  }

  @pragma('vm:prefer-inline')
  void emitEntrySuspendable(int ra, int rb, int rc) {
    _emitInstructionABC(Opcode.kEntrySuspendable, ra, rb, rc);
  }

  @pragma('vm:prefer-inline')
  void emitAllocateClosure(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kAllocateClosure, rd);
  }

  @pragma('vm:prefer-inline')
  void emitLoadClosureElement(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kLoadClosureElement, rd);
  }

  @pragma('vm:prefer-inline')
  void emitStoreClosureElement(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kStoreClosureElement, rd);
  }

  @pragma('vm:prefer-inline')
  void emitNullCheck(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kNullCheck, rd);
  }

  @pragma('vm:prefer-inline')
  void emitInitLateField(int rd) {
    emitSourcePosition();
    _emitInstructionD(Opcode.kInitLateField, rd);
  }

  @pragma('vm:prefer-inline')
  void emitPushUninitializedSentinel() {
    _emitInstruction0(Opcode.kPushUninitializedSentinel);
  }

  @pragma('vm:prefer-inline')
  void emitJumpIfInitialized(Label label) {
    _emitJumpInstruction(Opcode.kJumpIfInitialized, label);
  }

  @pragma('vm:prefer-inline')
  void emitAllocateRecord(int rd) {
    _emitInstructionD(Opcode.kAllocateRecord, rd);
  }

  @pragma('vm:prefer-inline')
  void emitLoadRecordField(int rd) {
    _emitInstructionD(Opcode.kLoadRecordField, rd);
  }

  @pragma('vm:prefer-inline')
  void recordCoverage(RecordedCoverageType type, int fileOffset) {
    if (!_recordCoverage) return;
    final index = recordedCoverageArray.add(type, fileOffset);
    _emitRecordCoverage(type.index, index);
  }

  @pragma('vm:prefer-inline')
  void _emitRecordCoverage(int ra, int re) {
    _emitInstructionAE(Opcode.kRecordCoverage, ra, re);
  }
}
