// 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.metadata.bytecode;

import 'package:kernel/ast.dart';
import '../bytecode/constant_pool.dart' show ConstantPool;
import '../bytecode/disassembler.dart' show BytecodeDisassembler;
import '../bytecode/exceptions.dart' show ExceptionsTable;

/// Metadata containing bytecode.
///
/// In kernel binary, bytecode metadata is encoded as following:
///
/// type BytecodeMetadata {
///   ConstantPool constantPool
///   List<Byte> bytecodes
///   ExceptionsTable exceptionsTable
///   List<ClosureBytecode> closures
/// }
///
/// type ClosureBytecode {
///   ConstantIndex closureFunction
///   List<Byte> bytecodes
///   ExceptionsTable exceptionsTable
/// }
///
/// Encoding of ExceptionsTable is described in
/// pkg/vm/lib/bytecode/exceptions.dart.
///
/// Encoding of ConstantPool is described in
/// pkg/vm/lib/bytecode/constant_pool.dart.
///
class BytecodeMetadata {
  final ConstantPool constantPool;
  final List<int> bytecodes;
  final ExceptionsTable exceptionsTable;
  final List<ClosureBytecode> closures;

  BytecodeMetadata(
      this.constantPool, this.bytecodes, this.exceptionsTable, this.closures);

  // TODO(alexmarkov): Consider printing constant pool before bytecode.
  @override
  String toString() => "\n"
      "Bytecode {\n"
      "${new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable)}}\n"
      "$exceptionsTable"
      "$constantPool"
      "${closures.join('\n')}";
}

/// Bytecode of a nested function (closure).
/// Closures share the constant pool of a top-level member.
class ClosureBytecode {
  final int closureFunctionConstantIndex;
  final List<int> bytecodes;
  final ExceptionsTable exceptionsTable;

  ClosureBytecode(
      this.closureFunctionConstantIndex, this.bytecodes, this.exceptionsTable);

  void writeToBinary(BinarySink sink) {
    sink.writeUInt30(closureFunctionConstantIndex);
    sink.writeByteList(bytecodes);
    exceptionsTable.writeToBinary(sink);
  }

  factory ClosureBytecode.readFromBinary(BinarySource source) {
    final closureFunctionConstantIndex = source.readUInt();
    final List<int> bytecodes = source.readByteList();
    final exceptionsTable = new ExceptionsTable.readFromBinary(source);
    return new ClosureBytecode(
        closureFunctionConstantIndex, bytecodes, exceptionsTable);
  }

  @override
  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.writeln('Closure CP#$closureFunctionConstantIndex {');
    sb.writeln(
        new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable));
    sb.writeln('}');
    return sb.toString();
  }
}

/// Repository for [BytecodeMetadata].
class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
  @override
  final String tag = 'vm.bytecode';

  @override
  final Map<TreeNode, BytecodeMetadata> mapping =
      <TreeNode, BytecodeMetadata>{};

  @override
  void writeToBinary(BytecodeMetadata metadata, Node node, BinarySink sink) {
    metadata.constantPool.writeToBinary(node, sink);
    sink.writeByteList(metadata.bytecodes);
    metadata.exceptionsTable.writeToBinary(sink);
    sink.writeUInt30(metadata.closures.length);
    metadata.closures.forEach((c) => c.writeToBinary(sink));
  }

  @override
  BytecodeMetadata readFromBinary(Node node, BinarySource source) {
    final ConstantPool constantPool =
        new ConstantPool.readFromBinary(node, source);
    final List<int> bytecodes = source.readByteList();
    final exceptionsTable = new ExceptionsTable.readFromBinary(source);
    final List<ClosureBytecode> closures = new List<ClosureBytecode>.generate(
        source.readUInt(), (_) => new ClosureBytecode.readFromBinary(source));
    return new BytecodeMetadata(
        constantPool, bytecodes, exceptionsTable, closures);
  }
}
