// 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.disassembler;

import 'dart:typed_data';

import 'package:vm/bytecode/dbc.dart';
import 'package:vm/bytecode/exceptions.dart';

class _Instruction {
  final Opcode opcode;
  final List<int> operands;
  _Instruction(this.opcode, this.operands);
}

class BytecodeDisassembler {
  static const int kOpcodeMask = 0xFF;
  static const int kBitsPerInt = 64;

  List<_Instruction> _instructions;
  int _labelCount;
  Map<int, String> _labels;
  Map<int, List<String>> _markers;

  String disassemble(List<int> bytecode, ExceptionsTable exceptionsTable) {
    _init(bytecode);
    _scanForJumpTargets();
    _markTryBlocks(exceptionsTable);
    return _disasm();
  }

  void _init(List<int> bytecode) {
    final uint8list = new Uint8List.fromList(bytecode);
    // TODO(alexmarkov): endianness?
    Uint32List words = uint8list.buffer.asUint32List();

    _instructions = new List<_Instruction>(words.length);
    for (int i = 0; i < words.length; i++) {
      _instructions[i] = _decodeInstruction(words[i]);
    }

    _labelCount = 0;
    _labels = <int, String>{};
    _markers = <int, List<String>>{};
  }

  _Instruction _decodeInstruction(int word) {
    final opcode = Opcode.values[word & kOpcodeMask];
    final format = BytecodeFormats[opcode];
    return new _Instruction(opcode, _decodeOperands(format, word));
  }

  List<int> _decodeOperands(Format format, int word) {
    switch (format.encoding) {
      case Encoding.k0:
        return const [];
      case Encoding.kA:
        return [_unsigned(word, 8, 8)];
      case Encoding.kAD:
        return [_unsigned(word, 8, 8), _unsigned(word, 16, 16)];
      case Encoding.kAX:
        return [_unsigned(word, 8, 8), _signed(word, 16, 16)];
      case Encoding.kD:
        return [_unsigned(word, 16, 16)];
      case Encoding.kX:
        return [_signed(word, 16, 16)];
      case Encoding.kABC:
        return [
          _unsigned(word, 8, 8),
          _unsigned(word, 16, 8),
          _unsigned(word, 24, 8)
        ];
      case Encoding.kABY:
        return [
          _unsigned(word, 8, 8),
          _unsigned(word, 16, 8),
          _signed(word, 24, 8)
        ];
      case Encoding.kT:
        return [_signed(word, 8, 24)];
    }
    throw 'Unexpected format $format';
  }

  int _unsigned(int word, int pos, int bits) =>
      (word >> pos) & ((1 << bits) - 1);

  int _signed(int word, int pos, int bits) =>
      _unsigned(word, pos, bits) <<
      (kBitsPerInt - bits) >>
      (kBitsPerInt - bits);

  void _scanForJumpTargets() {
    for (int i = 0; i < _instructions.length; i++) {
      final instr = _instructions[i];
      if (instr.opcode == Opcode.kJump) {
        final target = i + instr.operands[0];
        assert(0 <= target && target < _instructions.length);
        if (!_labels.containsKey(target)) {
          final label = 'L${++_labelCount}';
          _labels[target] = label;
          _addMarker(target, '$label:');
        }
      }
    }
  }

  void _markTryBlocks(ExceptionsTable exceptionsTable) {
    for (var tryBlock in exceptionsTable.blocks) {
      final int tryIndex = tryBlock.tryIndex;
      _addMarker(tryBlock.startPC, 'Try #$tryIndex start:');
      _addMarker(tryBlock.endPC, 'Try #$tryIndex end:');
      _addMarker(tryBlock.handlerPC, 'Try #$tryIndex handler:');
    }
  }

  void _addMarker(int pc, String marker) {
    final markers = (_markers[pc] ??= <String>[]);
    markers.add(marker);
  }

  String _disasm() {
    StringBuffer out = new StringBuffer();
    for (int i = 0; i < _instructions.length; i++) {
      List<String> markers = _markers[i];
      if (markers != null) {
        markers.forEach(out.writeln);
      }
      _writeInstruction(out, i, _instructions[i]);
    }
    return out.toString();
  }

  void _writeInstruction(StringBuffer out, int bci, _Instruction instr) {
    final format = BytecodeFormats[instr.opcode];
    assert(format != null);

    out.write('  ');

    const int kOpcodeWidth = 20;
    const String kOpcodePrefix = 'Opcode.k';

    String opcode = instr.opcode.toString();
    assert(opcode.startsWith(kOpcodePrefix));
    opcode = opcode.substring(kOpcodePrefix.length);

    if (instr.operands.isEmpty) {
      out.writeln(opcode);
      return;
    }

    out.write(opcode.padRight(kOpcodeWidth));

    for (int i = 0; i < instr.operands.length; i++) {
      if (i == 0) {
        out.write(' ');
      } else {
        out.write(', ');
      }
      final operand =
          _formatOperand(bci, format.operands[i], instr.operands[i]);
      out.write(operand);
    }

    out.writeln();
  }

  String _formatOperand(int bci, Operand fmt, int value) {
    switch (fmt) {
      case Operand.none:
        break;
      case Operand.imm:
        return '$value';
      case Operand.lit:
        return 'CP#$value';
      case Operand.reg:
        return 'r$value';
      case Operand.xeg:
        return (value < 0) ? 'FP[$value]' : 'r$value';
      case Operand.tgt:
        return _labels[bci + value] ?? (throw 'Label not found');
      case Operand.spe:
        return SpecialIndex.values[value]
            .toString()
            .substring('SpecialIndex.'.length);
    }
    throw 'Unexpected operand format $fmt';
  }
}
