| package org.eclipse.e4.languages.javascript.rhino.jsdi; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.e4.languages.javascript.debug.connect.DisconnectException; |
| import org.eclipse.e4.languages.javascript.debug.connect.Request; |
| import org.eclipse.e4.languages.javascript.debug.connect.Response; |
| import org.eclipse.e4.languages.javascript.debug.connect.TimeoutException; |
| import org.eclipse.e4.languages.javascript.jsdi.StackFrame; |
| import org.eclipse.e4.languages.javascript.jsdi.ThreadReference; |
| |
| public class ThreadReferenceImpl extends MirrorImpl implements ThreadReference { |
| |
| private Number threadId; |
| private List frames = new ArrayList(); |
| private int status = THREAD_STATUS_RUNNING; |
| private boolean suspended; |
| private boolean atBreakpoint = false; |
| private String name; |
| private String step; |
| |
| public ThreadReferenceImpl(VirtualMachineImpl vm, Map jsonThread) { |
| super(vm); |
| this.threadId = (Number) jsonThread.get("threadId"); |
| this.name = (String) jsonThread.get("name"); |
| if (this.name == null) |
| this.name = "Rhino thread - " + threadId; |
| this.suspended = "suspended".equals(jsonThread.get("state")); |
| } |
| |
| private ThreadReferenceImpl(VirtualMachineImpl vm, Long threadId) { |
| super(vm); |
| this.threadId = threadId; |
| this.name = "Rhino thread - " + threadId; |
| this.status = THREAD_STATUS_ZOMBIE; |
| this.frames = Collections.EMPTY_LIST; |
| } |
| |
| public synchronized int frameCount() { |
| frames(); |
| return frames.size(); |
| } |
| |
| public synchronized StackFrame frame(int index) { |
| frames(); |
| return (StackFrame) frames.get(index); |
| } |
| |
| public synchronized List frames() { |
| if (status == THREAD_STATUS_ZOMBIE) |
| return frames; |
| |
| if (!suspended) |
| throw new IllegalStateException("not suspended"); |
| |
| if (frames != null) |
| return frames; |
| |
| Request request = new Request("frames"); |
| request.getArguments().put("threadId", threadId); |
| try { |
| Response response = vm.sendRequest(request, 30000); |
| List frameIds = (List) response.getBody().get("frames"); |
| if (frameIds.isEmpty()) { |
| frames = Collections.EMPTY_LIST; |
| return frames; |
| } |
| frames = new ArrayList(); |
| for (Iterator iterator = frameIds.iterator(); iterator.hasNext();) { |
| Long frameId = new Long(((Number) iterator.next()).longValue()); |
| StackFrameImpl frame = createStackFrame(frameId); |
| frames.add(frame); |
| } |
| } catch (DisconnectException e) { |
| e.printStackTrace(); |
| } catch (TimeoutException e) { |
| e.printStackTrace(); |
| } |
| return frames; |
| } |
| |
| private StackFrameImpl createStackFrame(Long frameId) { |
| Request request = new Request("frame"); |
| request.getArguments().put("threadId", threadId); |
| request.getArguments().put("frameId", frameId); |
| try { |
| Response response = vm.sendRequest(request, 30000); |
| Map jsonFrame = (Map) response.getBody().get("frame"); |
| return new StackFrameImpl(vm, jsonFrame); |
| } catch (DisconnectException e) { |
| e.printStackTrace(); |
| } catch (TimeoutException e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| |
| public synchronized boolean isAtBreakpoint() { |
| return suspended && atBreakpoint; |
| } |
| |
| public synchronized void markSuspended(boolean atBreakpoint) { |
| this.suspended = true; |
| this.atBreakpoint = atBreakpoint; |
| } |
| |
| public synchronized boolean isSuspended() { |
| return suspended; |
| } |
| |
| public String name() { |
| return name; |
| } |
| |
| public synchronized void resume() { |
| if (status == THREAD_STATUS_ZOMBIE) { |
| return; |
| } |
| Request request = new Request("continue"); |
| request.getArguments().put("threadId", threadId); |
| if (step != null) { |
| request.getArguments().put("step", step); |
| } |
| |
| try { |
| Response response = vm.sendRequest(request, 30000); |
| if (response.isSuccess()) { |
| frames = null; |
| suspended = false; |
| atBreakpoint = false; |
| } |
| } catch (DisconnectException e) { |
| e.printStackTrace(); |
| } catch (TimeoutException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void suspend() { |
| if (status == THREAD_STATUS_ZOMBIE) { |
| return; |
| } |
| |
| Request request = new Request("suspend"); |
| request.getArguments().put("threadId", threadId); |
| try { |
| vm.sendRequest(request, 30000); |
| // TODO: really make this work |
| suspended = true; |
| } catch (DisconnectException e) { |
| e.printStackTrace(); |
| } catch (TimeoutException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void interrupt() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| public synchronized int status() { |
| return status; |
| } |
| |
| public synchronized String getStep() { |
| return step; |
| } |
| |
| public synchronized void setStep(String step) { |
| this.step = step; |
| } |
| |
| public static ThreadReferenceImpl zombie(VirtualMachineImpl vm, Long threadId) { |
| return new ThreadReferenceImpl(vm, threadId); |
| } |
| |
| } |