org.chromium.debug.core/src/org/chromium/debug/core/model/JavascriptThread.java
changeset 2 e4420d2515f1
child 52 f577ea64429e
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.debug.core.model;
       
     6 
       
     7 import java.util.List;
       
     8 
       
     9 import org.chromium.debug.core.ChromiumDebugPlugin;
       
    10 import org.chromium.sdk.CallFrame;
       
    11 import org.chromium.sdk.DebugContext.StepAction;
       
    12 import org.eclipse.core.runtime.IAdaptable;
       
    13 import org.eclipse.debug.core.DebugEvent;
       
    14 import org.eclipse.debug.core.DebugException;
       
    15 import org.eclipse.debug.core.model.IBreakpoint;
       
    16 import org.eclipse.debug.core.model.IStackFrame;
       
    17 import org.eclipse.debug.core.model.IThread;
       
    18 import org.eclipse.osgi.util.NLS;
       
    19 
       
    20 /**
       
    21  * This class represents the only Chromium V8 VM thread.
       
    22  */
       
    23 public class JavascriptThread extends DebugElementImpl implements IThread, IAdaptable {
       
    24 
       
    25   private static final StackFrame[] EMPTY_FRAMES = new StackFrame[0];
       
    26 
       
    27   /**
       
    28    * Breakpoints this thread is suspended at or <code>null</code> if none.
       
    29    */
       
    30   private IBreakpoint[] breakpoints;
       
    31 
       
    32   /**
       
    33    * Whether this thread is stepping. V8 does not provide information if the
       
    34    * thread is actually stepping or it is running past the last "steppable"
       
    35    * statement.
       
    36    */
       
    37   private boolean isStepping = false;
       
    38 
       
    39   /**
       
    40    * Cached stack
       
    41    */
       
    42   private StackFrame[] stackFrames;
       
    43 
       
    44   /**
       
    45    * Constructs a new thread for the given target
       
    46    *
       
    47    * @param debugTarget this thread is created for
       
    48    */
       
    49   public JavascriptThread(IChromiumDebugTarget debugTarget) {
       
    50     super(debugTarget);
       
    51   }
       
    52 
       
    53   public StackFrame[] getStackFrames() throws DebugException {
       
    54     if (isSuspended()) {
       
    55       ensureStackFrames();
       
    56       return stackFrames;
       
    57     } else {
       
    58       return EMPTY_FRAMES;
       
    59     }
       
    60   }
       
    61 
       
    62   public void reset() {
       
    63     this.stackFrames = null;
       
    64   }
       
    65 
       
    66   private void ensureStackFrames() {
       
    67     this.stackFrames = wrapStackFrames(getDebugTarget().getDebugContext().getCallFrames());
       
    68   }
       
    69 
       
    70   private StackFrame[] wrapStackFrames(List<? extends CallFrame> jsFrames) {
       
    71     StackFrame[] frames = new StackFrame[jsFrames.size()];
       
    72     for (int i = 0, size = frames.length; i < size; ++i) {
       
    73       frames[i] = new StackFrame(getDebugTarget(), this, jsFrames.get(i));
       
    74     }
       
    75     return frames;
       
    76   }
       
    77 
       
    78   public boolean hasStackFrames() throws DebugException {
       
    79     return isSuspended();
       
    80   }
       
    81 
       
    82   public int getPriority() throws DebugException {
       
    83     return 0;
       
    84   }
       
    85 
       
    86   public IStackFrame getTopStackFrame() throws DebugException {
       
    87     IStackFrame[] frames = getStackFrames();
       
    88     if (frames.length > 0) {
       
    89       return frames[0];
       
    90     }
       
    91     return null;
       
    92   }
       
    93 
       
    94   public String getName() throws DebugException {
       
    95     String url = getDebugTarget().getJavascriptEmbedder().getThreadName();
       
    96     return NLS.bind(Messages.JsThread_ThreadLabelFormat, (isSuspended()
       
    97         ? Messages.JsThread_ThreadLabelSuspended
       
    98         : Messages.JsThread_ThreadLabelRunning), (url.length() > 0
       
    99         ? (" : " + url) : "")); //$NON-NLS-1$ //$NON-NLS-2$
       
   100   }
       
   101 
       
   102   public IBreakpoint[] getBreakpoints() {
       
   103     if (breakpoints == null) {
       
   104       return new IBreakpoint[0];
       
   105     }
       
   106     return breakpoints;
       
   107   }
       
   108 
       
   109   protected void setBreakpoints(IBreakpoint[] breakpoints) {
       
   110     this.breakpoints = breakpoints;
       
   111   }
       
   112 
       
   113   public boolean canResume() {
       
   114     return isSuspended();
       
   115   }
       
   116 
       
   117   public boolean canSuspend() {
       
   118     return getDebugTarget().canSuspend();
       
   119   }
       
   120 
       
   121   public boolean isSuspended() {
       
   122     return getDebugTarget().isSuspended();
       
   123   }
       
   124 
       
   125   public void resume() throws DebugException {
       
   126     setStepping(false);
       
   127     getDebugTarget().resume();
       
   128   }
       
   129 
       
   130   public void suspend() throws DebugException {
       
   131     getDebugTarget().suspend();
       
   132   }
       
   133 
       
   134   public boolean canStepInto() {
       
   135     return isSuspended();
       
   136   }
       
   137 
       
   138   public boolean canStepOver() {
       
   139     return isSuspended();
       
   140   }
       
   141 
       
   142   public boolean canStepReturn() {
       
   143     return isSuspended();
       
   144   }
       
   145 
       
   146   public boolean isStepping() {
       
   147     return isStepping;
       
   148   }
       
   149 
       
   150   private void step(StepAction stepAction, int detail) throws DebugException {
       
   151     setStepping(true);
       
   152     getDebugTarget().getDebugContext().continueVm(stepAction, 1, null);
       
   153     // The suspend event should be fired once the backtrace is ready
       
   154     // (in BacktraceProcessor).
       
   155     getDebugTarget().fireResumeEvent(detail);
       
   156   }
       
   157 
       
   158   public void stepInto() throws DebugException {
       
   159     step(StepAction.IN, DebugEvent.STEP_INTO);
       
   160   }
       
   161 
       
   162   public void stepOver() throws DebugException {
       
   163     step(StepAction.OVER, DebugEvent.STEP_OVER);
       
   164   }
       
   165 
       
   166   public void stepReturn() throws DebugException {
       
   167     step(StepAction.OUT, DebugEvent.STEP_RETURN);
       
   168   }
       
   169 
       
   170   public boolean canTerminate() {
       
   171     return getDebugTarget().canTerminate();
       
   172   }
       
   173 
       
   174   public boolean isTerminated() {
       
   175     return getDebugTarget().isTerminated();
       
   176   }
       
   177 
       
   178   public void terminate() throws DebugException {
       
   179     getDebugTarget().terminate();
       
   180   }
       
   181 
       
   182   /**
       
   183    * Sets whether this thread is stepping.
       
   184    */
       
   185   protected void setStepping(boolean stepping) {
       
   186     isStepping = stepping;
       
   187   }
       
   188 
       
   189   @Override
       
   190   @SuppressWarnings("unchecked")
       
   191   public Object getAdapter(Class adapter) {
       
   192     if (adapter == StackFrame.class) {
       
   193       try {
       
   194         return getTopStackFrame();
       
   195       } catch (DebugException e) {
       
   196         ChromiumDebugPlugin.log(e);
       
   197       }
       
   198     }
       
   199     return super.getAdapter(adapter);
       
   200   }
       
   201 }