// Copyright (c) 2018, 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.

library vm.bytecode.source_positions;

import 'bytecode_serialization.dart' show BufferedWriter, BufferedReader;

/// Maintains mapping between bytecode instructions and source positions.
class SourcePositions {
  final Map<int, int> mapping = <int, int>{}; // PC -> fileOffset
  int _lastPc = 0;
  int _lastOffset = 0;

  SourcePositions();

  void add(int pc, int fileOffset) {
    assert(pc > _lastPc);
    assert(fileOffset >= 0);
    if (fileOffset != _lastOffset) {
      mapping[pc] = fileOffset;
      _lastPc = pc;
      _lastOffset = fileOffset;
    }
  }

  void writeContents(BufferedWriter writer) {
    writer.writePackedUInt30(mapping.length);
    final encodePC = new PackedUInt30DeltaEncoder();
    final encodeOffset = new SLEB128DeltaEncoder();
    mapping.forEach((int pc, int fileOffset) {
      encodePC.write(writer, pc);
      encodeOffset.write(writer, fileOffset);
    });
  }

  void write(BufferedWriter writer) {
    // TODO(alexmarkov): write source positions in a separate section
    BufferedWriter contentsWriter = new BufferedWriter.fromWriter(writer);
    writeContents(contentsWriter);

    final contents = contentsWriter.takeBytes();
    writer.writePackedUInt30(contents.length);
    writer.writeBytes(contents);
  }

  SourcePositions.read(BufferedReader reader) {
    reader.readPackedUInt30(); // Contents length in bytes.
    final int length = reader.readPackedUInt30();
    final decodePC = new PackedUInt30DeltaDecoder();
    final decodeOffset = new SLEB128DeltaDecoder();
    for (int i = 0; i < length; ++i) {
      int pc = decodePC.read(reader);
      int fileOffset = decodeOffset.read(reader);
      add(pc, fileOffset);
    }
  }

  @override
  String toString() => mapping.toString();

  Map<int, String> getBytecodeAnnotations() {
    return mapping.map((int pc, int fileOffset) =>
        new MapEntry(pc, 'source position $fileOffset'));
  }
}

class PackedUInt30DeltaEncoder {
  int _last = 0;

  void write(BufferedWriter write, int value) {
    write.writePackedUInt30(value - _last);
    _last = value;
  }
}

class PackedUInt30DeltaDecoder {
  int _last = 0;

  int read(BufferedReader reader) {
    int value = reader.readPackedUInt30() + _last;
    _last = value;
    return value;
  }
}

class SLEB128DeltaEncoder {
  int _last = 0;

  void write(BufferedWriter writer, int value) {
    writer.writeSLEB128(value - _last);
    _last = value;
  }
}

class SLEB128DeltaDecoder {
  int _last = 0;

  int read(BufferedReader reader) {
    int value = reader.readSLEB128() + _last;
    _last = value;
    return value;
  }
}
