bool dwarf_cfa_state_iterator::next()

in Source/PLCrashAsyncDwarfCFAState.cpp [309:342]


bool dwarf_cfa_state_iterator<machine_ptr, machine_ptr_s>::next (dwarf_cfa_state_regnum_t *regnum, plcrash_dwarf_cfa_reg_rule_t *rule, machine_ptr *value) {
    /* Fetch the next entry in the bucket chain */
    if (_cur_entry_idx != DWARF_CFA_STATE_INVALID_ENTRY_IDX) {
        _cur_entry_idx = _stack->_entries[_cur_entry_idx].next;
        
        /* Advance to the next bucket if we've reached the end of the current chain */
        if (_cur_entry_idx == DWARF_CFA_STATE_INVALID_ENTRY_IDX)
            _bucket_idx++;
    }
    
    /*
     * On the first iteration, or after the end of a bucket chain has been reached, find the next valid bucket chain.
     * Otherwise, we have a valid bucket chain and simply need the next entry.
     */
    if (_cur_entry_idx == DWARF_CFA_STATE_INVALID_ENTRY_IDX) {
        for (; _bucket_idx < DWARF_CFA_STATE_BUCKET_COUNT; _bucket_idx++) {
            if (_stack->_table_stack[_stack->_table_depth][_bucket_idx] != DWARF_CFA_STATE_INVALID_ENTRY_IDX) {
                _cur_entry_idx = _stack->_table_stack[_stack->_table_depth][_bucket_idx];
                break;
            }
        }
        
        /* If we get here without a valid entry, we've hit the end of all bucket chains. */
        if (_cur_entry_idx == DWARF_CFA_STATE_INVALID_ENTRY_IDX)
            return false;
    }
    
    
    typename dwarf_cfa_state<machine_ptr, machine_ptr_s>::dwarf_cfa_reg_entry_t *entry = &_stack->_entries[_cur_entry_idx];
    *regnum = entry->regnum;
    *value = (machine_ptr)entry->value;
    *rule = (plcrash_dwarf_cfa_reg_rule_t) entry->rule;
    return true;
}