// 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 'package:kernel/ast.dart';

import 'dbc.dart' show constantPoolIndexLimit, BytecodeLimitExceededException;
import 'bytecode_serialization.dart'
    show
        BufferedWriter,
        BufferedReader,
        BytecodeSizeStatistics,
        NamedEntryStatistics,
        StringTable;
import 'object_table.dart' show ObjectHandle, ObjectTable;

enum ConstantTag {
  kInvalid,
  kObjectRef,
  kClass,
  kType,
  kStaticField,
  kInstanceField,
  kTypeArgumentsField,
  kClosureFunction,
  kEndClosureFunctionScope,
  kSubtypeTestCache,
  kEmptyTypeArguments,
  kDirectCall,
  kInterfaceCall,
  kInstantiatedInterfaceCall,
  kDynamicCall,
  kExternalCall,
  kNativeFunction,
  kDeferredLibraryPrefix,
  kAllocateClosure,
}

String constantTagToString(ConstantTag tag) =>
    tag.toString().substring('ConstantTag.k'.length);

abstract class ConstantPoolEntry {
  const ConstantPoolEntry();

  ConstantTag get tag;

  // Returns number of extra reserved constant pool entries
  // following this entry.
  int get numReservedEntries => 0;

  void write(BufferedWriter writer) {
    writer.writeByte(tag.index);
    writeValue(writer);
  }

  void writeValue(BufferedWriter writer);

  factory ConstantPoolEntry.read(BufferedReader reader) {
    ConstantTag tag = ConstantTag.values[reader.readByte()];
    switch (tag) {
      case ConstantTag.kInvalid:
        break;
      case ConstantTag.kStaticField:
        return new ConstantStaticField.read(reader);
      case ConstantTag.kInstanceField:
        return new ConstantInstanceField.read(reader);
      case ConstantTag.kClass:
        return new ConstantClass.read(reader);
      case ConstantTag.kTypeArgumentsField:
        return new ConstantTypeArgumentsField.read(reader);
      case ConstantTag.kType:
        return new ConstantType.read(reader);
      case ConstantTag.kClosureFunction:
        return new ConstantClosureFunction.read(reader);
      case ConstantTag.kEndClosureFunctionScope:
        return new ConstantEndClosureFunctionScope.read(reader);
      case ConstantTag.kSubtypeTestCache:
        return new ConstantSubtypeTestCache.read(reader);
      case ConstantTag.kEmptyTypeArguments:
        return new ConstantEmptyTypeArguments.read(reader);
      case ConstantTag.kObjectRef:
        return new ConstantObjectRef.read(reader);
      case ConstantTag.kDirectCall:
        return new ConstantDirectCall.read(reader);
      case ConstantTag.kInterfaceCall:
        return new ConstantInterfaceCall.read(reader);
      case ConstantTag.kInstantiatedInterfaceCall:
        return new ConstantInstantiatedInterfaceCall.read(reader);
      case ConstantTag.kDynamicCall:
        return new ConstantDynamicCall.read(reader);
      case ConstantTag.kExternalCall:
        return new ConstantExternalCall.read(reader);
      case ConstantTag.kNativeFunction:
        return new ConstantNativeFunction.read(reader);
      case ConstantTag.kDeferredLibraryPrefix:
        return new ConstantDeferredLibraryPrefix.read(reader);
      case ConstantTag.kAllocateClosure:
        return new ConstantAllocateClosure.read(reader);
    }
    throw 'Unexpected constant tag $tag';
  }
}

enum InvocationKind {
  method, // x.foo(...) or foo(...)
  getter, // x.foo
  setter, // x.foo = ...
}

class ConstantStaticField extends ConstantPoolEntry {
  final ObjectHandle field;

  ConstantStaticField(this.field);

  @override
  ConstantTag get tag => ConstantTag.kStaticField;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(field);
  }

  ConstantStaticField.read(BufferedReader reader)
    : field = reader.readPackedObject();

  @override
  String toString() => 'StaticField $field';

  @override
  int get hashCode => field.hashCode;

  @override
  bool operator ==(other) =>
      other is ConstantStaticField && this.field == other.field;
}

class ConstantInstanceField extends ConstantPoolEntry {
  final ObjectHandle field;

  int get numReservedEntries => 1;

  ConstantInstanceField(this.field);

  @override
  ConstantTag get tag => ConstantTag.kInstanceField;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(field);
  }

  ConstantInstanceField.read(BufferedReader reader)
    : field = reader.readPackedObject();

  @override
  String toString() => 'InstanceField $field';

  @override
  int get hashCode => field.hashCode;

  @override
  bool operator ==(other) =>
      other is ConstantInstanceField && this.field == other.field;
}

class ConstantClass extends ConstantPoolEntry {
  final ObjectHandle classHandle;

  ConstantClass(this.classHandle);

  @override
  ConstantTag get tag => ConstantTag.kClass;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(classHandle);
  }

  ConstantClass.read(BufferedReader reader)
    : classHandle = reader.readPackedObject();

  @override
  String toString() => 'Class $classHandle';

  @override
  int get hashCode => classHandle.hashCode;

  @override
  bool operator ==(other) =>
      other is ConstantClass && this.classHandle == other.classHandle;
}

class ConstantTypeArgumentsField extends ConstantPoolEntry {
  final ObjectHandle classHandle;

  ConstantTypeArgumentsField(this.classHandle);

  @override
  ConstantTag get tag => ConstantTag.kTypeArgumentsField;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(classHandle);
  }

  ConstantTypeArgumentsField.read(BufferedReader reader)
    : classHandle = reader.readPackedObject();

  @override
  String toString() => 'TypeArgumentsField $classHandle';

  @override
  int get hashCode => classHandle.hashCode;

  @override
  bool operator ==(other) =>
      other is ConstantTypeArgumentsField &&
      this.classHandle == other.classHandle;
}

class ConstantType extends ConstantPoolEntry {
  final ObjectHandle type;

  ConstantType(this.type);

  @override
  ConstantTag get tag => ConstantTag.kType;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(type);
  }

  ConstantType.read(BufferedReader reader) : type = reader.readPackedObject();

  @override
  String toString() => 'Type $type';

  @override
  int get hashCode => type.hashCode;

  @override
  bool operator ==(other) => other is ConstantType && this.type == other.type;
}

class ConstantClosureFunction extends ConstantPoolEntry {
  final int closureIndex;

  ConstantClosureFunction(this.closureIndex);

  @override
  ConstantTag get tag => ConstantTag.kClosureFunction;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedUInt30(closureIndex);
  }

  ConstantClosureFunction.read(BufferedReader reader)
    : closureIndex = reader.readPackedUInt30();

  @override
  String toString() {
    return 'ClosureFunction $closureIndex';
  }

  @override
  int get hashCode => closureIndex;

  @override
  bool operator ==(other) =>
      other is ConstantClosureFunction &&
      this.closureIndex == other.closureIndex;
}

class ConstantEndClosureFunctionScope extends ConstantPoolEntry {
  ConstantEndClosureFunctionScope();

  @override
  ConstantTag get tag => ConstantTag.kEndClosureFunctionScope;

  @override
  void writeValue(BufferedWriter writer) {}

  ConstantEndClosureFunctionScope.read(BufferedReader reader) {}

  @override
  String toString() => 'EndClosureFunctionScope';

  // ConstantEndClosureFunctionScope entries are created per closure and should
  // not be merged, so ConstantEndClosureFunctionScope class uses identity
  // [hashCode] and [operator ==].
}

class ConstantSubtypeTestCache extends ConstantPoolEntry {
  ConstantSubtypeTestCache();

  @override
  ConstantTag get tag => ConstantTag.kSubtypeTestCache;

  @override
  void writeValue(BufferedWriter writer) {}

  ConstantSubtypeTestCache.read(BufferedReader reader);

  @override
  String toString() => 'SubtypeTestCache';

  // ConstantSubtypeTestCache entries are created per subtype test site and
  // should not be merged, so ConstantSubtypeTestCache class uses identity
  // [hashCode] and [operator ==].

  @override
  int get hashCode => identityHashCode(this);

  @override
  bool operator ==(other) => identical(this, other);
}

class ConstantEmptyTypeArguments extends ConstantPoolEntry {
  const ConstantEmptyTypeArguments();

  @override
  ConstantTag get tag => ConstantTag.kEmptyTypeArguments;

  @override
  void writeValue(BufferedWriter writer) {}

  ConstantEmptyTypeArguments.read(BufferedReader reader);

  @override
  String toString() => 'EmptyTypeArguments';

  @override
  int get hashCode => 997;

  @override
  bool operator ==(other) => other is ConstantEmptyTypeArguments;
}

class ConstantObjectRef extends ConstantPoolEntry {
  final ObjectHandle? object;

  ConstantObjectRef(this.object);

  @override
  ConstantTag get tag => ConstantTag.kObjectRef;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(object);
  }

  ConstantObjectRef.read(BufferedReader reader)
    : object = reader.readPackedObject();

  @override
  String toString() => 'ObjectRef $object';

  @override
  int get hashCode => object.hashCode;

  @override
  bool operator ==(other) =>
      other is ConstantObjectRef && this.object == other.object;
}

class ConstantDirectCall extends ConstantPoolEntry {
  final ObjectHandle target;
  final ObjectHandle argDesc;

  ConstantDirectCall(this.target, this.argDesc);

  // Reserve 1 extra slot for arguments descriptor, following target slot.
  int get numReservedEntries => 1;

  @override
  ConstantTag get tag => ConstantTag.kDirectCall;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(target);
    writer.writePackedObject(argDesc);
  }

  ConstantDirectCall.read(BufferedReader reader)
    : target = reader.readPackedObject(),
      argDesc = reader.readPackedObject();

  @override
  String toString() => "DirectCall '$target', $argDesc";

  @override
  int get hashCode => _combineHashes(target.hashCode, argDesc.hashCode);

  @override
  bool operator ==(other) =>
      other is ConstantDirectCall &&
      this.target == other.target &&
      this.argDesc == other.argDesc;
}

class ConstantInterfaceCall extends ConstantPoolEntry {
  final ObjectHandle target;
  final ObjectHandle argDesc;

  ConstantInterfaceCall(this.target, this.argDesc);

  // Reserve 1 extra slot for arguments descriptor, following target slot.
  int get numReservedEntries => 1;

  @override
  ConstantTag get tag => ConstantTag.kInterfaceCall;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(target);
    writer.writePackedObject(argDesc);
  }

  ConstantInterfaceCall.read(BufferedReader reader)
    : target = reader.readPackedObject(),
      argDesc = reader.readPackedObject();

  @override
  String toString() => "InterfaceCall '$target', $argDesc";

  @override
  int get hashCode => _combineHashes(target.hashCode, argDesc.hashCode);

  @override
  bool operator ==(other) =>
      other is ConstantInterfaceCall &&
      this.target == other.target &&
      this.argDesc == other.argDesc;
}

class ConstantInstantiatedInterfaceCall extends ConstantPoolEntry {
  final ObjectHandle target;
  final ObjectHandle argDesc;
  final ObjectHandle staticReceiverType;

  ConstantInstantiatedInterfaceCall(
    this.target,
    this.argDesc,
    this.staticReceiverType,
  );

  // Reserve 2 extra slots (3 slots total).
  int get numReservedEntries => 2;

  @override
  ConstantTag get tag => ConstantTag.kInstantiatedInterfaceCall;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(target);
    writer.writePackedObject(argDesc);
    writer.writePackedObject(staticReceiverType);
  }

  ConstantInstantiatedInterfaceCall.read(BufferedReader reader)
    : target = reader.readPackedObject(),
      argDesc = reader.readPackedObject(),
      staticReceiverType = reader.readPackedObject();

  @override
  String toString() =>
      "InstantiatedInterfaceCall '$target', $argDesc, receiver $staticReceiverType";

  @override
  int get hashCode => _combineHashes(
    _combineHashes(target.hashCode, argDesc.hashCode),
    staticReceiverType.hashCode,
  );

  @override
  bool operator ==(other) =>
      other is ConstantInstantiatedInterfaceCall &&
      this.target == other.target &&
      this.argDesc == other.argDesc &&
      this.staticReceiverType == other.staticReceiverType;
}

class ConstantDynamicCall extends ConstantPoolEntry {
  final ObjectHandle selectorName;
  final ObjectHandle argDesc;

  ConstantDynamicCall(this.selectorName, this.argDesc);

  // Reserve 1 extra slot for arguments descriptor, following selector slot.
  int get numReservedEntries => 1;

  @override
  ConstantTag get tag => ConstantTag.kDynamicCall;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(selectorName);
    writer.writePackedObject(argDesc);
  }

  ConstantDynamicCall.read(BufferedReader reader)
    : selectorName = reader.readPackedObject(),
      argDesc = reader.readPackedObject();

  @override
  String toString() => 'DynamicCall $selectorName, $argDesc';

  @override
  int get hashCode => _combineHashes(selectorName.hashCode, argDesc.hashCode);

  @override
  bool operator ==(other) =>
      other is ConstantDynamicCall &&
      this.selectorName == other.selectorName &&
      this.argDesc == other.argDesc;
}

class ConstantExternalCall extends ConstantPoolEntry {
  ConstantExternalCall();

  @override
  ConstantTag get tag => ConstantTag.kExternalCall;

  @override
  int get numReservedEntries => 1;

  @override
  void writeValue(BufferedWriter writer) {}

  ConstantExternalCall.read(BufferedReader reader);

  @override
  String toString() => 'ExternalCall';

  // Do not merge ConstantExternalCall entries.

  @override
  int get hashCode => identityHashCode(this);

  @override
  bool operator ==(other) => identical(this, other);
}

class ConstantNativeFunction extends ConstantPoolEntry {
  ConstantNativeFunction();

  @override
  ConstantTag get tag => ConstantTag.kNativeFunction;

  @override
  void writeValue(BufferedWriter writer) {}

  ConstantNativeFunction.read(BufferedReader reader);

  @override
  String toString() => 'NativeFunction';

  // Do not merge ConstantNativeFunction entries.

  @override
  int get hashCode => identityHashCode(this);

  @override
  bool operator ==(other) => identical(this, other);
}

class ConstantDeferredLibraryPrefix extends ConstantPoolEntry {
  final ObjectHandle name;
  final ObjectHandle enclosingLibrary;
  final ObjectHandle targetLibrary;

  ConstantDeferredLibraryPrefix(
    this.name,
    this.enclosingLibrary,
    this.targetLibrary,
  );

  @override
  ConstantTag get tag => ConstantTag.kDeferredLibraryPrefix;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedObject(name);
    writer.writePackedObject(enclosingLibrary);
    writer.writePackedObject(targetLibrary);
  }

  ConstantDeferredLibraryPrefix.read(BufferedReader reader)
    : name = reader.readPackedObject(),
      enclosingLibrary = reader.readPackedObject(),
      targetLibrary = reader.readPackedObject();

  @override
  String toString() =>
      'DeferredLibraryPrefix $name, $enclosingLibrary -> $targetLibrary';

  @override
  int get hashCode => _combineHashes(
    name.hashCode,
    _combineHashes(enclosingLibrary.hashCode, targetLibrary.hashCode),
  );

  @override
  bool operator ==(other) =>
      other is ConstantDeferredLibraryPrefix &&
      this.name == other.name &&
      this.enclosingLibrary == other.enclosingLibrary &&
      this.targetLibrary == other.targetLibrary;
}

class ConstantAllocateClosure extends ConstantPoolEntry {
  static const int hasDelayedTypeArguments = 1 << 0;
  static const int hasInstantiatorTypeArguments = 1 << 1;
  static const int hasFunctionTypeArguments = 1 << 2;

  final int closureIndex;
  final int numElements;
  final int flags;

  ConstantAllocateClosure(this.closureIndex, this.numElements, this.flags);

  @override
  ConstantTag get tag => ConstantTag.kAllocateClosure;

  // 2 slots: function, encoded length and flags.
  @override
  int get numReservedEntries => 1;

  @override
  void writeValue(BufferedWriter writer) {
    writer.writePackedUInt30(closureIndex);
    writer.writePackedUInt30(numElements);
    writer.writePackedUInt30(flags);
  }

  ConstantAllocateClosure.read(BufferedReader reader)
    : closureIndex = reader.readPackedUInt30(),
      numElements = reader.readPackedUInt30(),
      flags = reader.readPackedUInt30();

  @override
  String toString() {
    return 'AllocateClosure $closureIndex, num-elements: $numElements, flags: $flags';
  }

  @override
  int get hashCode => closureIndex.hashCode;

  @override
  bool operator ==(other) =>
      other is ConstantAllocateClosure &&
      this.closureIndex == other.closureIndex &&
      this.flags == other.flags &&
      this.numElements == other.numElements;
}

/// Reserved constant pool entry.
class _ReservedConstantPoolEntry extends ConstantPoolEntry {
  const _ReservedConstantPoolEntry();

  ConstantTag get tag => throw 'This constant pool entry is reserved';
  void writeValue(BufferedWriter writer) =>
      throw 'This constant pool entry is reserved';

  @override
  String toString() => 'Reserved';
}

class ConstantPool {
  final StringTable stringTable;
  final ObjectTable objectTable;
  final List<ConstantPoolEntry> entries = <ConstantPoolEntry>[];
  final Map<ConstantPoolEntry, int> _canonicalizationCache =
      <ConstantPoolEntry, int>{};

  ConstantPool(this.stringTable, this.objectTable);

  int addString(String value) => addObjectRef(new StringConstant(value));

  int addName(String name) =>
      _add(new ConstantObjectRef(objectTable.getPublicNameHandle(name)));

  int addArgDesc(
    int numArguments, {
    int numTypeArgs = 0,
    List<String> argNames = const <String>[],
  }) => _add(
    new ConstantObjectRef(
      objectTable.getArgDescHandle(numArguments, numTypeArgs, argNames),
    ),
  );

  int addArgDescByArguments(Arguments args, {bool hasReceiver = false}) => _add(
    new ConstantObjectRef(
      objectTable.getArgDescHandleByArguments(args, hasReceiver: hasReceiver),
    ),
  );

  int addDirectCall(
    InvocationKind invocationKind,
    Member target,
    ObjectHandle argDesc,
  ) {
    final targetHandle = objectTable.getMemberHandle(
      target,
      isGetter: invocationKind == InvocationKind.getter,
      isSetter: invocationKind == InvocationKind.setter,
    );
    return _add(new ConstantDirectCall(targetHandle, argDesc));
  }

  int addInterfaceCall(
    InvocationKind invocationKind,
    Member target,
    ObjectHandle argDesc,
  ) => _add(
    new ConstantInterfaceCall(
      objectTable.getMemberHandle(
        target,
        isGetter: invocationKind == InvocationKind.getter,
        isSetter: invocationKind == InvocationKind.setter,
      ),
      argDesc,
    ),
  );

  int addInstantiatedInterfaceCall(
    InvocationKind invocationKind,
    Member target,
    ObjectHandle argDesc,
    DartType staticReceiverType,
  ) => _add(
    new ConstantInstantiatedInterfaceCall(
      objectTable.getMemberHandle(
        target,
        isGetter: invocationKind == InvocationKind.getter,
        isSetter: invocationKind == InvocationKind.setter,
      ),
      argDesc,
      objectTable.getHandle(staticReceiverType)!,
    ),
  );

  int addDynamicCall(
    InvocationKind invocationKind,
    Name selector,
    ObjectHandle argDesc,
  ) => _add(
    new ConstantDynamicCall(
      objectTable.getSelectorNameHandle(
        selector,
        isGetter: invocationKind == InvocationKind.getter,
        isSetter: invocationKind == InvocationKind.setter,
      ),
      argDesc,
    ),
  );

  int addInstanceCall(
    InvocationKind invocationKind,
    Member? target,
    Name targetName,
    ObjectHandle argDesc,
  ) => (target == null)
      ? addDynamicCall(invocationKind, targetName, argDesc)
      : addInterfaceCall(invocationKind, target, argDesc);

  int addExternalCall() => _add(ConstantExternalCall());

  int addNativeFunction() => _add(ConstantNativeFunction());

  int addStaticField(Field field) =>
      _add(new ConstantStaticField(objectTable.getHandle(field)!));

  int addInstanceField(Field field) =>
      _add(new ConstantInstanceField(objectTable.getHandle(field)!));

  int addClass(Class node) =>
      _add(new ConstantClass(objectTable.getHandle(node)!));

  int addTypeArgumentsField(Class node) =>
      _add(new ConstantTypeArgumentsField(objectTable.getHandle(node)!));

  int addType(DartType type) =>
      _add(new ConstantType(objectTable.getHandle(type)!));

  int addTypeArguments(List<DartType>? typeArgs) =>
      _add(new ConstantObjectRef(objectTable.getTypeArgumentsHandle(typeArgs)));

  int addClosureFunction(int closureIndex) =>
      _add(new ConstantClosureFunction(closureIndex));

  int addEndClosureFunctionScope() =>
      _add(new ConstantEndClosureFunctionScope());

  int addSubtypeTestCache() => _add(new ConstantSubtypeTestCache());

  int addEmptyTypeArguments() => _add(const ConstantEmptyTypeArguments());

  int addDeferredLibraryPrefix(
    String name,
    Library enclosingLibrary,
    Library targetLibrary,
  ) => _add(
    ConstantDeferredLibraryPrefix(
      objectTable.getConstStringHandle(name),
      objectTable.getHandle(enclosingLibrary)!,
      objectTable.getHandle(targetLibrary)!,
    ),
  );

  int addObjectRef(Node? node) {
    // Constant objects should not depend on the type parameters of
    // the enclosing function.
    return objectTable.withoutEnclosingFunctionTypeParameters(
      () => _add(new ConstantObjectRef(objectTable.getHandle(node))),
    );
  }

  int addSelectorName(Name name, InvocationKind invocationKind) => _add(
    new ConstantObjectRef(
      objectTable.getSelectorNameHandle(
        name,
        isGetter: invocationKind == InvocationKind.getter,
        isSetter: invocationKind == InvocationKind.setter,
      ),
    ),
  );

  int addAllocateClosure(
    int closureIndex,
    int numElements, {
    required bool hasDelayedTypeArguments,
    required bool hasInstantiatorTypeArguments,
    required bool hasFunctionTypeArguments,
  }) => _add(
    ConstantAllocateClosure(
      closureIndex,
      numElements,
      (hasDelayedTypeArguments
              ? ConstantAllocateClosure.hasDelayedTypeArguments
              : 0) |
          (hasInstantiatorTypeArguments
              ? ConstantAllocateClosure.hasInstantiatorTypeArguments
              : 0) |
          (hasFunctionTypeArguments
              ? ConstantAllocateClosure.hasFunctionTypeArguments
              : 0),
    ),
  );

  int _add(ConstantPoolEntry entry) {
    int? index = _canonicalizationCache[entry];
    if (index == null) {
      index = entries.length;
      if (index >= constantPoolIndexLimit) {
        throw new ConstantPoolIndexOverflowException();
      }
      _addEntry(entry);
      _canonicalizationCache[entry] = index;
    }
    return index;
  }

  void _addEntry(ConstantPoolEntry entry) {
    entries.add(entry);
    for (int i = 0; i < entry.numReservedEntries; ++i) {
      entries.add(const _ReservedConstantPoolEntry());
    }
  }

  void write(BufferedWriter writer) {
    final start = writer.offset;
    if (BytecodeSizeStatistics.constantPoolStats.isEmpty) {
      for (var tag in ConstantTag.values) {
        BytecodeSizeStatistics.constantPoolStats.add(
          new NamedEntryStatistics(constantTagToString(tag)),
        );
      }
    }
    writer.writePackedUInt30(entries.length);
    entries.forEach((e) {
      if (e is _ReservedConstantPoolEntry) {
        return;
      }

      final entryStart = writer.offset;

      e.write(writer);

      final entryStat = BytecodeSizeStatistics.constantPoolStats[e.tag.index];
      entryStat.size += (writer.offset - entryStart);
      ++entryStat.count;
    });
    BytecodeSizeStatistics.constantPoolSize += (writer.offset - start);
  }

  ConstantPool.read(BufferedReader reader)
    : stringTable = reader.stringReader as StringTable,
      objectTable = reader.objectReader as ObjectTable {
    int len = reader.readPackedUInt30();
    for (int i = 0; i < len; i++) {
      final e = new ConstantPoolEntry.read(reader);
      _addEntry(e);
      i += e.numReservedEntries;
    }
  }

  @override
  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.writeln('ConstantPool {');
    for (int i = 0; i < entries.length; i++) {
      sb.writeln('  [$i] = ${entries[i]}');
    }
    sb.writeln('}');
    return sb.toString();
  }
}

int _combineHashes(int hash1, int hash2) =>
    (((hash1 * 31) & 0x3fffffff) + hash2) & 0x3fffffff;

class ConstantPoolIndexOverflowException
    extends BytecodeLimitExceededException {}
