org.chromium.sdk/src/org/chromium/sdk/internal/tools/v8/processor/BreakpointProcessor.java
changeset 2 e4420d2515f1
equal deleted inserted replaced
1:ef76fc2ac88c 2:e4420d2515f1
       
     1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style license that can be
       
     3 // found in the LICENSE file.
       
     4 
       
     5 package org.chromium.sdk.internal.tools.v8.processor;
       
     6 
       
     7 import java.util.ArrayList;
       
     8 import java.util.Collection;
       
     9 import java.util.Collections;
       
    10 import java.util.List;
       
    11 
       
    12 import org.chromium.sdk.Breakpoint;
       
    13 import org.chromium.sdk.ExceptionData;
       
    14 import org.chromium.sdk.internal.ContextBuilder;
       
    15 import org.chromium.sdk.internal.DebugSession;
       
    16 import org.chromium.sdk.internal.ExceptionDataImpl;
       
    17 import org.chromium.sdk.internal.InternalContext;
       
    18 import org.chromium.sdk.internal.InternalContext.ContextDismissedCheckedException;
       
    19 import org.chromium.sdk.internal.protocol.BreakEventBody;
       
    20 import org.chromium.sdk.internal.protocol.EventNotification;
       
    21 import org.chromium.sdk.internal.protocol.data.SomeHandle;
       
    22 import org.chromium.sdk.internal.protocol.data.ValueHandle;
       
    23 import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException;
       
    24 import org.chromium.sdk.internal.tools.v8.BreakpointManager;
       
    25 import org.chromium.sdk.internal.tools.v8.V8Helper;
       
    26 import org.chromium.sdk.internal.tools.v8.V8Protocol;
       
    27 import org.chromium.sdk.internal.tools.v8.request.DebuggerMessage;
       
    28 import org.chromium.sdk.internal.tools.v8.request.DebuggerMessageFactory;
       
    29 
       
    30 /**
       
    31  * Handles the suspension-related V8 command replies and events.
       
    32  */
       
    33 public class BreakpointProcessor extends V8EventProcessor {
       
    34 
       
    35   /** The name of the "exception" object to report as a variable name. */
       
    36   private static final String EXCEPTION_NAME = "exception";
       
    37 
       
    38   public BreakpointProcessor(DebugSession debugSession) {
       
    39     super(debugSession);
       
    40   }
       
    41 
       
    42   @Override
       
    43   public void messageReceived(EventNotification eventMessage) {
       
    44     final boolean isEvent = true;
       
    45     if (isEvent) {
       
    46       String event = eventMessage.getEvent();
       
    47       DebugSession debugSession = getDebugSession();
       
    48 
       
    49       ContextBuilder contextBuilder = debugSession.getContextBuilder();
       
    50 
       
    51       ContextBuilder.ExpectingBreakEventStep step1 = contextBuilder.buildNewContext();
       
    52 
       
    53       InternalContext internalContext = step1.getInternalContext();
       
    54 
       
    55       BreakEventBody breakEventBody;
       
    56       try {
       
    57         breakEventBody = eventMessage.getBody().asBreakEventBody();
       
    58       } catch (JsonProtocolParseException e) {
       
    59         throw new RuntimeException(e);
       
    60       }
       
    61 
       
    62       ContextBuilder.ExpectingBacktraceStep step2;
       
    63       if (V8Protocol.EVENT_BREAK.key.equals(event)) {
       
    64         Collection<Breakpoint> breakpointsHit = getBreakpointsHit(eventMessage, breakEventBody);
       
    65         step2 = step1.setContextState(breakpointsHit, null);
       
    66       } else if (V8Protocol.EVENT_EXCEPTION.key.equals(event)) {
       
    67         ExceptionData exception = createException(eventMessage, breakEventBody,
       
    68             internalContext);
       
    69         step2 = step1.setContextState(Collections.<Breakpoint> emptySet(), exception);
       
    70       } else {
       
    71         contextBuilder.buildSequenceFailure();
       
    72         throw new RuntimeException();
       
    73       }
       
    74 
       
    75       processNextStep(step2);
       
    76     }
       
    77   }
       
    78 
       
    79   public void processNextStep(ContextBuilder.ExpectingBacktraceStep step2) {
       
    80     BacktraceProcessor backtraceProcessor = new BacktraceProcessor(step2);
       
    81     InternalContext internalContext = step2.getInternalContext();
       
    82 
       
    83     DebuggerMessage message = DebuggerMessageFactory.backtrace(null, null, true);
       
    84     try {
       
    85       // Command is not immediate because we are supposed to be suspended.
       
    86       internalContext.sendV8CommandAsync(message, false, backtraceProcessor, null);
       
    87     } catch (ContextDismissedCheckedException e) {
       
    88       // Can't happen -- we are just creating context, it couldn't have become invalid
       
    89       throw new RuntimeException(e);
       
    90     }
       
    91   }
       
    92 
       
    93   private Collection<Breakpoint> getBreakpointsHit(EventNotification response,
       
    94       BreakEventBody breakEventBody) {
       
    95     List<Long> breakpointIdsArray = breakEventBody.getBreakpoints();
       
    96     BreakpointManager breakpointManager = getDebugSession().getBreakpointManager();
       
    97     if (breakpointIdsArray == null) {
       
    98       // Suspended on step end.
       
    99       return Collections.<Breakpoint> emptySet();
       
   100     }
       
   101     Collection<Breakpoint> breakpointsHit = new ArrayList<Breakpoint>(breakpointIdsArray.size());
       
   102     for (int i = 0, size = breakpointIdsArray.size(); i < size; ++i) {
       
   103       Breakpoint existingBp = breakpointManager.getBreakpoint(breakpointIdsArray.get(i));
       
   104       if (existingBp != null) {
       
   105         breakpointsHit.add(existingBp);
       
   106       }
       
   107     }
       
   108     return breakpointsHit;
       
   109   }
       
   110 
       
   111   private ExceptionData createException(EventNotification response, BreakEventBody body,
       
   112       InternalContext internalContext) {
       
   113     List<SomeHandle> refs = response.getRefs();
       
   114     ValueHandle exception = body.getException();
       
   115     List<SomeHandle> handles = new ArrayList<SomeHandle>(refs.size() + 1);
       
   116     handles.addAll(refs);
       
   117     handles.add(exception.getSuper());
       
   118     internalContext.getHandleManager().putAll(handles);
       
   119 
       
   120     // source column is not exposed ("sourceColumn" in "body")
       
   121     String sourceText = body.getSourceLineText();
       
   122 
       
   123     return new ExceptionDataImpl(internalContext,
       
   124         V8Helper.createMirrorFromLookup(exception).getValueMirror(),
       
   125         EXCEPTION_NAME,
       
   126         body.isUncaught(),
       
   127         sourceText,
       
   128         exception.text());
       
   129   }
       
   130 
       
   131 }