Exemple #1
0
bool Debugger::hasBreakpoint(SourceID sourceID, const TextPosition& position, Breakpoint *hitBreakpoint)
{
    if (!m_breakpointsActivated)
        return false;

    SourceIDToBreakpointsMap::const_iterator it = m_sourceIDToBreakpoints.find(sourceID);
    if (it == m_sourceIDToBreakpoints.end())
        return false;

    unsigned line = position.m_line.zeroBasedInt();
    unsigned column = position.m_column.zeroBasedInt();

    LineToBreakpointsMap::const_iterator breaksIt = it->value.find(line);
    if (breaksIt == it->value.end())
        return false;

    bool hit = false;
    const BreakpointsList& breakpoints = *breaksIt->value;
    Breakpoint* breakpoint;
    for (breakpoint = breakpoints.head(); breakpoint; breakpoint = breakpoint->next()) {
        unsigned breakLine = breakpoint->line;
        unsigned breakColumn = breakpoint->column;
        // Since frontend truncates the indent, the first statement in a line must match the breakpoint (line,0).
        ASSERT(this == m_currentCallFrame->codeBlock()->globalObject()->debugger());
        if ((line != m_lastExecutedLine && line == breakLine && !breakColumn)
            || (line == breakLine && column == breakColumn)) {
            hit = true;
            break;
        }
    }
    if (!hit)
        return false;

    if (hitBreakpoint)
        *hitBreakpoint = *breakpoint;

    if (breakpoint->condition.isEmpty())
        return true;

    // We cannot stop in the debugger while executing condition code,
    // so make it looks like the debugger is already paused.
    TemporaryPausedState pausedState(*this);

    JSValue exception;
    DebuggerCallFrame* debuggerCallFrame = currentDebuggerCallFrame();
    JSValue result = debuggerCallFrame->evaluate(breakpoint->condition, exception);

    // We can lose the debugger while executing JavaScript.
    if (!m_currentCallFrame)
        return false;

    if (exception) {
        // An erroneous condition counts as "false".
        handleExceptionInBreakpointCondition(m_currentCallFrame, exception);
        return false;
    }

    return result.toBoolean(m_currentCallFrame);
}
Exemple #2
0
BreakpointID Debugger::setBreakpoint(Breakpoint& breakpoint, bool& existing)
{
    ASSERT(breakpoint.resolved);
    ASSERT(breakpoint.sourceID != noSourceID);

    SourceID sourceID = breakpoint.sourceID;
    unsigned line = breakpoint.line;
    unsigned column = breakpoint.column;

    SourceIDToBreakpointsMap::iterator it = m_sourceIDToBreakpoints.find(breakpoint.sourceID);
    if (it == m_sourceIDToBreakpoints.end())
        it = m_sourceIDToBreakpoints.set(sourceID, LineToBreakpointsMap()).iterator;

    LineToBreakpointsMap::iterator breaksIt = it->value.find(line);
    if (breaksIt == it->value.end())
        breaksIt = it->value.set(line, adoptRef(new BreakpointsList)).iterator;

    BreakpointsList& breakpoints = *breaksIt->value;
    for (Breakpoint* current = breakpoints.head(); current; current = current->next()) {
        if (current->column == column) {
            // Found existing breakpoint. Do not create a duplicate at this location.
            existing = true;
            return current->id;
        }
    }

    existing = false;
    BreakpointID id = ++m_topBreakpointID;
    RELEASE_ASSERT(id != noBreakpointID);

    breakpoint.id = id;

    Breakpoint* newBreakpoint = new Breakpoint(breakpoint);
    breakpoints.append(newBreakpoint);
    m_breakpointIDToBreakpoint.set(id, newBreakpoint);

    toggleBreakpoint(*newBreakpoint, BreakpointEnabled);

    return id;
}
Exemple #3
0
BreakpointID Debugger::setBreakpoint(Breakpoint breakpoint, unsigned& actualLine, unsigned& actualColumn)
{
    SourceID sourceID = breakpoint.sourceID;
    unsigned line = breakpoint.line;
    unsigned column = breakpoint.column;

    SourceIDToBreakpointsMap::iterator it = m_sourceIDToBreakpoints.find(sourceID);
    if (it == m_sourceIDToBreakpoints.end())
        it = m_sourceIDToBreakpoints.set(sourceID, LineToBreakpointsMap()).iterator;
    LineToBreakpointsMap::iterator breaksIt = it->value.find(line);
    if (breaksIt == it->value.end())
        breaksIt = it->value.set(line, adoptRef(new BreakpointsList)).iterator;

    BreakpointsList& breakpoints = *breaksIt->value;
    for (Breakpoint* current = breakpoints.head(); current; current = current->next()) {
        if (current->column == column) {
            // The breakpoint already exists. We're not allowed to create a new
            // breakpoint at this location. Rather than returning the breakpointID
            // of the pre-existing breakpoint, we need to return noBreakpointID
            // to indicate that we're not creating a new one.
            return noBreakpointID;
        }
    }

    BreakpointID id = ++m_topBreakpointID;
    RELEASE_ASSERT(id != noBreakpointID);

    breakpoint.id = id;
    actualLine = line;
    actualColumn = column;

    Breakpoint* newBreakpoint = new Breakpoint(breakpoint);
    breakpoints.append(newBreakpoint);
    m_breakpointIDToBreakpoint.set(id, newBreakpoint);

    toggleBreakpoint(breakpoint, BreakpointEnabled);

    return id;
}
Exemple #4
0
void Debugger::removeBreakpoint(BreakpointID id)
{
    ASSERT(id != noBreakpointID);

    BreakpointIDToBreakpointMap::iterator idIt = m_breakpointIDToBreakpoint.find(id);
    ASSERT(idIt != m_breakpointIDToBreakpoint.end());
    Breakpoint* breakpoint = idIt->value;

    SourceID sourceID = breakpoint->sourceID;
    ASSERT(sourceID);
    SourceIDToBreakpointsMap::iterator it = m_sourceIDToBreakpoints.find(sourceID);
    ASSERT(it != m_sourceIDToBreakpoints.end());
    LineToBreakpointsMap::iterator breaksIt = it->value.find(breakpoint->line);
    ASSERT(breaksIt != it->value.end());

    toggleBreakpoint(*breakpoint, BreakpointDisabled);

    BreakpointsList& breakpoints = *breaksIt->value;
#if !ASSERT_DISABLED
    bool found = false;
    for (Breakpoint* current = breakpoints.head(); current && !found; current = current->next()) {
        if (current->id == breakpoint->id)
            found = true;
    }
    ASSERT(found);
#endif

    m_breakpointIDToBreakpoint.remove(idIt);
    breakpoints.remove(breakpoint);
    delete breakpoint;

    if (breakpoints.isEmpty()) {
        it->value.remove(breaksIt);
        if (it->value.isEmpty())
            m_sourceIDToBreakpoints.remove(it);
    }
}