#-------------------------------------------------------------------------------
# elftools: dwarf/lineprogram.py
#
# DWARF line number program
#
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
import copy

from ..common.utils import struct_parse
from .constants import *


class LineState(object):
    """ Represents a line program state (or a "row" in the matrix
        describing debug location information for addresses).
        The instance variables of this class are the "state machine registers"
        described in section 6.2.2 of DWARFv3
    """
    def __init__(self, default_is_stmt):
        self.address = 0
        self.file = 1
        self.line = 1
        self.column = 0
        self.is_stmt = default_is_stmt
        self.basic_block = False
        self.end_sequence = False
        self.prologue_end = False
        self.epilogue_begin = False
        self.isa = 0

    def __repr__(self):
        a = ['<LineState %x:' % id(self)]
        a.append('  address = 0x%x' % self.address)
        for attr in ('file', 'line', 'column', 'is_stmt', 'basic_block',
                     'end_sequence', 'prologue_end', 'epilogue_begin', 'isa'):
            a.append('  %s = %s' % (attr, getattr(self, attr)))
        return '\n'.join(a) + '>\n'

class LineProgram(object):
    """ Builds a "line table", which is essentially the matrix described
        in section 6.2 of DWARFv3. It's a list of LineState objects,
        sorted by increasing address, so it can be used to obtain the
        state information for each address.
    """
    def __init__(self, header, dwarfinfo, structs,
                 program_start_offset, program_end_offset):
        """ 
            header:
                The header of this line program. Note: LineProgram may modify
                its header by appending file entries if DW_LNE_define_file
                instructions are encountered.

            dwarfinfo:
                The DWARFInfo context object which created this one

            structs:
                A DWARFStructs instance suitable for this line program

            program_{start|end}_offset:
                Offset in the debug_line section stream where this program
                starts, and where it ends. The actual range includes start
                but not end: [start, end - 1]
        """
        self.dwarfinfo = dwarfinfo
        self.stream = self.dwarfinfo.debug_line_sec.stream
        self.header = header
        self.structs = structs
        self.program_start_offset = program_start_offset
        self.program_end_offset = program_end_offset

        self._line_table = None

    def get_line_table(self):
        """ Get the decoded line table for this line program
        """
        if self._line_table is None:
            self._line_table = self._decode_line_program()
        return self._line_table

    #------ PRIVATE ------#
    
    def __getitem__(self, name):
        """ Implement dict-like access to header entries
        """
        return self.header[name]

    def _decode_line_program(self):
        linetable = []
        state = LineState(self.header['default_is_stmt'])

        def add_state_to_table():
            # Used by instructions that have to add the current state to the
            # line table. After adding, some state registers have to be
            # cleared.
            linetable.append(copy.copy(state))
            state.basic_block = False
            state.prologue_end = False
            state.epilogue_begin = False

        offset = self.program_start_offset
        while offset < self.program_end_offset:
            opcode = struct_parse(
                self.structs.Dwarf_uint8(''), 
                self.stream,
                offset)

            # As an exercise in avoiding premature optimization, if...elif
            # chains are used here for standard and extended opcodes instead
            # of dispatch tables. This keeps the code much cleaner. Besides,
            # the majority of instructions in a typical program are special
            # opcodes anyway.
            if opcode >= self.header['opcode_base']:
                # Special opcode (follow the recipe in 6.2.5.1)
                adjusted_opcode = opcode - self['opcode_base']
                state.address += ((adjusted_opcode / self['line_range']) *
                                  self['minimum_instruction_length'])
                state.line += (self['line_base'] + 
                              adjusted_opcode % self['line_range'])
                add_state_to_table()
            elif opcode == 0:
                # Extended opcode: start with a zero byte, followed by
                # instruction size and the instruction itself.
                inst_len = struct_parse(self.structs.Dwarf_uleb128(''),
                                        self.stream)
                ex_opcode = struct_parse(self.structs.Dwarf_uint8(''),
                                         self.stream)

                if ex_opcode == DW_LNE_end_sequence:
                    state.end_sequence = True
                    add_state_to_table()
                    # reset state
                    state = LineState(self.header['default_is_stmt']) 
                elif ex_opcode == DW_LNE_set_address:
                    operand = struct_parse(self.structs.Dwarf_target_addr(''),
                                           self.stream)
                    state.address = operand
                elif ex_opcode == DW_LNE_define_file:
                    operand = struct_parse(
                        self.structs.Dwarf_lineprog_file_entry, self.stream)
                    self['file_entry'].append(operand)
            else: # 0 < opcode < opcode_base
                # Standard opcode
                if opcode == DW_LNS_copy:
                    add_state_to_table()
                elif opcode == DW_LNS_advance_pc:
                    operand = struct_parse(self.structs.Dwarf_uleb128(''),
                                           self.stream)
                    state.address += (
                        operand * self.header['minimum_instruction_length'])
                elif opcode == DW_LNS_advance_line:
                    operand = struct_parse(self.structs.Dwarf_sleb128(''),
                                           self.stream)
                    state.line += operand
                elif opcode == DW_LNS_set_file:
                    operand = struct_parse(self.structs.Dwarf_sleb128(''),
                                           self.stream)
                    state.file = operand
                elif opcode == DW_LNS_set_column:
                    operand = struct_parse(self.structs.Dwarf_uleb128(''),
                                           self.stream)
                    state.column = operand
                elif opcode == DW_LNS_negate_stmt:
                    state.is_stmt = not state.is_stmt
                elif opcode == DW_LNS_set_basic_block:
                    state.basic_block = True
                elif opcode == DW_LNS_const_add_pc:
                    adjusted_opcode = 255 - self['opcode_base']
                    state.address += ((adjusted_opcode / self['line_range']) *
                                      self['minimum_instruction_length'])
                elif opcode == DW_LNS_fixed_advance_pc:
                    operand = struct_parse(self.structs.Dwarf_uint16,
                                           self.stream)
                    state.address += operand
                elif opcode == DW_LNS_set_prologue_end:
                    state.prologue_end = True
                elif opcode == DW_LNS_set_epilogue_begin:
                    state.epilogue_begin = True
                elif opcode == DW_LNS_set_isa:
                    operand = struct_parse(self.structs.Dwarf_uleb128(''),
                                           self.stream)
                    state.isa = operand
                else:
                    dwarf_assert(False, 'Invalid standard line program opcode: %s' % (
                        opcode,))
            offset = self.stream.tell()
        return linetable

