org.chromium.sdk/src/org/chromium/sdk/internal/tools/v8/processor/BacktraceProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/org.chromium.sdk/src/org/chromium/sdk/internal/tools/v8/processor/BacktraceProcessor.java Wed Dec 23 17:13:18 2009 -0800
@@ -0,0 +1,148 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.sdk.internal.tools.v8.processor;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.chromium.sdk.DebugContext;
+import org.chromium.sdk.JavascriptVm;
+import org.chromium.sdk.Script;
+import org.chromium.sdk.internal.ContextBuilder;
+import org.chromium.sdk.internal.DebugSession;
+import org.chromium.sdk.internal.FrameMirror;
+import org.chromium.sdk.internal.HandleManager;
+import org.chromium.sdk.internal.protocol.BacktraceCommandBody;
+import org.chromium.sdk.internal.protocol.CommandResponse;
+import org.chromium.sdk.internal.protocol.FrameObject;
+import org.chromium.sdk.internal.protocol.SuccessCommandResponse;
+import org.chromium.sdk.internal.protocol.data.ScriptHandle;
+import org.chromium.sdk.internal.protocol.data.SomeHandle;
+import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException;
+import org.chromium.sdk.internal.tools.v8.DebuggerCommand;
+import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil;
+import org.json.simple.JSONObject;
+
+/**
+ * Handles the "backtrace" V8 command replies.
+ */
+class BacktraceProcessor implements org.chromium.sdk.internal.tools.v8.V8CommandProcessor.V8HandlerCallback {
+
+ private final ContextBuilder.ExpectingBacktraceStep step2;
+
+ BacktraceProcessor(ContextBuilder.ExpectingBacktraceStep step2) {
+ this.step2 = step2;
+ }
+
+ public void messageReceived(CommandResponse response) {
+ String commandString = response.getCommand();
+
+ DebuggerCommand command = DebuggerCommand.forString(commandString);
+ if (command != DebuggerCommand.BACKTRACE) {
+ handleWrongStacktrace();
+ }
+ SuccessCommandResponse successResponse = response.asSuccess();
+ if (successResponse == null) {
+ handleWrongStacktrace();
+ }
+
+ final DebugContext debugContext = setFrames(successResponse);
+ final DebugSession debugSession = step2.getInternalContext().getDebugSession();
+
+ JavascriptVm.ScriptsCallback afterScriptsAreLoaded = new JavascriptVm.ScriptsCallback() {
+ public void failure(String errorMessage) {
+ handleWrongStacktrace();
+ }
+
+ public void success(Collection<Script> scripts) {
+ debugSession.getDebugEventListener().suspended(debugContext);
+ }
+ };
+
+ debugSession.getScriptLoader().loadAllScripts(afterScriptsAreLoaded, null);
+ }
+
+ private DebugContext setFrames(SuccessCommandResponse response) {
+ BacktraceCommandBody body;
+ try {
+ body = response.getBody().asBacktraceCommandBody();
+ } catch (JsonProtocolParseException e) {
+ throw new RuntimeException(e);
+ }
+ List<FrameObject> jsonFrames = body.getFrames();
+ int frameCnt = jsonFrames.size();
+ FrameMirror[] frameMirrors = new FrameMirror[frameCnt];
+
+ HandleManager handleManager = step2.getInternalContext().getHandleManager();
+
+ List<SomeHandle> refs = response.getRefs();
+ handleManager.putAll(refs);
+ for (int frameIdx = 0; frameIdx < frameCnt; frameIdx++) {
+ FrameObject frameObject = jsonFrames.get(frameIdx);
+ int index = (int) frameObject.getIndex();
+ FrameObject frame = jsonFrames.get(frameIdx);
+ JSONObject func = frame.getFunc();
+
+ String text = frame.getText().replace('\r', ' ').replace('\n', ' ');
+ Matcher m = FRAME_TEXT_PATTERN.matcher(text);
+ m.matches();
+ String url = m.group(1);
+
+ int currentLine = (int) frame.getLine();
+
+ // If we stopped because of the debuggerword then we're on the next
+ // line.
+ // TODO(apavlov): Terry says: we need to use the [e.g. Rhino] AST to
+ // decide if line is debuggerword. If so, find the next sequential line.
+ // The below works for simple scripts but doesn't take into account
+ // comments, etc.
+ String srcLine = frame.getSourceLineText();
+ if (srcLine.trim().startsWith(DEBUGGER_RESERVED)) {
+ currentLine++;
+ }
+ Long scriptRef = V8ProtocolUtil.getObjectRef(frame.getScript());
+
+ Long scriptId = -1L;
+ if (scriptRef != null) {
+ SomeHandle handle = handleManager.getHandle(scriptRef);
+ ScriptHandle scriptHandle;
+ try {
+ scriptHandle = handle.asScriptHandle();
+ } catch (JsonProtocolParseException e) {
+ throw new RuntimeException(e);
+ }
+ if (handle != null) {
+ scriptId = scriptHandle.id();
+ }
+ }
+ frameMirrors[index] =
+ new FrameMirror(frameObject, url, currentLine, scriptId,
+ V8ProtocolUtil.getFunctionName(func));
+ }
+
+
+ return step2.setFrames(frameMirrors);
+ }
+
+ public void failure(String message) {
+ handleWrongStacktrace();
+ }
+
+ private void handleWrongStacktrace() {
+ step2.getInternalContext().getContextBuilder().buildSequenceFailure();
+ }
+
+ private static final String DEBUGGER_RESERVED = "debugger";
+
+ /** Regex for the "text" field of the "backtrace" element response. */
+ private static final String FRAME_TEXT_REGEX =
+ "^(?:.+) ([^\\s]+) line (.+) column (.+)" + " (?:\\(position (.+)\\))?";
+
+ /** A pattern for the frame "text" regex. */
+ private static final Pattern FRAME_TEXT_PATTERN = Pattern.compile(FRAME_TEXT_REGEX);
+
+}