You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ft...@apache.org on 2014/04/30 11:59:02 UTC
[13/15] FLEX-34291: Merge the donated FDB with the current one.
http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/379cb609/modules/debugger/src/java/flash/tools/debugger/concrete/DManager.java
----------------------------------------------------------------------
diff --git a/modules/debugger/src/java/flash/tools/debugger/concrete/DManager.java b/modules/debugger/src/java/flash/tools/debugger/concrete/DManager.java
index a290b14..a8b1c8a 100644
--- a/modules/debugger/src/java/flash/tools/debugger/concrete/DManager.java
+++ b/modules/debugger/src/java/flash/tools/debugger/concrete/DManager.java
@@ -1,34 +1,37 @@
/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package flash.tools.debugger.concrete;
import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import flash.tools.debugger.Isolate;
import flash.tools.debugger.SourceLocator;
import flash.tools.debugger.SuspendReason;
+import flash.tools.debugger.SwfInfo;
import flash.tools.debugger.Value;
import flash.tools.debugger.VariableAttribute;
import flash.tools.debugger.VariableType;
@@ -39,9 +42,9 @@ import flash.tools.debugger.events.DivideByZeroFault;
import flash.tools.debugger.events.ExceptionFault;
import flash.tools.debugger.events.FaultEvent;
import flash.tools.debugger.events.FileListModifiedEvent;
-import flash.tools.debugger.events.InvalidTargetFault;
-import flash.tools.debugger.events.InvalidURLFault;
import flash.tools.debugger.events.InvalidWithFault;
+import flash.tools.debugger.events.IsolateCreateEvent;
+import flash.tools.debugger.events.IsolateExitEvent;
import flash.tools.debugger.events.ProtoLimitFault;
import flash.tools.debugger.events.RecursionLimitFault;
import flash.tools.debugger.events.ScriptTimeoutFault;
@@ -52,262 +55,374 @@ import flash.tools.debugger.events.TraceEvent;
import flash.util.Trace;
/**
- * Implements the receiving and updating of debug state from the socket connection
- * of the Flash Player.
+ * Implements the receiving and updating of debug state from the socket
+ * connection of the Flash Player.
*/
-public class DManager implements DProtocolNotifierIF, SourceLocator
-{
- private final HashMap<String, String> m_parms;
- private final Map<Integer,DModule> m_source; /* WARNING: accessed from multiple threads */
- private final ArrayList<DLocation> m_breakpoints; /* WARNING: accessed from multiple threads */
- private final ArrayList<DSwfInfo> m_swfInfo; /* WARNING: accessed from multiple threads */
- private final ArrayList<DWatch> m_watchpoints; /* WARNING: accessed from multiple threads */
+public class DManager implements DProtocolNotifierIF, SourceLocator {
+ private final HashMap<String, String> m_parms;
- /**
- * The currently active stack frames.
- */
- private ArrayList<DStackContext> m_frames;
+ private final HashMap<Integer, DIsolate> m_isolates; /*
+ * WARNING: accessed
+ * from multiple threads
+ */
/**
- * The stack frames that were active the last time the player was suspended.
+ * The currently active isolate or worker
*/
- private ArrayList<DStackContext> m_previousFrames;
+ private Isolate m_activeIsolate = DEFAULT_ISOLATE;
+
+ private LinkedList<DebugEvent> m_event; /*
+ * our event queue; WARNING:
+ * accessed from multiple threads
+ */
+ private SourceLocator m_sourceLocator;
+
+
+ private boolean m_squelchEnabled; /*
+ * true if we are talking to a squelch
+ * enabled debug player
+ */
+ private int m_playerVersion; /*
+ * player version number obtained from InVersion
+ * message; e.g. 9 for Flash Player 9.0
+ */
+
+ private boolean m_sourceListModified; /*
+ * deprecated; indicates m_source has
+ * changed since last call to
+ * getSource(). WARNING: lock with
+ * synchronized (m_source) { ... }
+ */
+ private byte[] m_actions; /* deprecated */
+ private String[] m_lastConstantPool; /* deprecated */
- /**
- * A list of all known variables in the player. Stored as a mapping
- * from an object's id to its DValue.
- */
- private Map<Long,DValue> m_values;
+ // SWF/SWD fetching and parsing
+ private String m_uri;
+ private byte[] m_swf; // latest swf obtained from get swf
+ private byte[] m_swd; // latest swd obtained from get swd
+
+ private Map<String, String> m_options = new HashMap<String, String>(); // Player
+ // options
+ // that
+ // have
+ // been
+ // queried
+ // by
+ // OutGetOption,
+ // and
+ // come
+ // back
+ // via
+ // InOption
- /**
- * A list of all known variables in the player from the previous time
- * the player was suspended. Stored as a mapping from an object's id
- * to its DValue.
- */
- private Map<Long,DValue> m_previousValues;
-
- private LinkedList<DebugEvent> m_event; /* our event queue; WARNING: accessed from multiple threads */
- private DSuspendInfo m_suspendInfo; /* info for when we are stopped */
- private SourceLocator m_sourceLocator;
-
- private DSwfInfo m_lastSwfInfo; /* hack for syncing swfinfo records with incoming InScript messages */
- private DVariable m_lastInGetVariable;/* hack for getVariable call to work with getters */
- private boolean m_attachChildren; /* hack for getVariable call to work with getters */
- private DVariable m_lastInCallFunction; /* hack for callFunction to work */
- private DVariable m_lastInBinaryOp;
- private boolean m_squelchEnabled; /* true if we are talking to a squelch enabled debug player */
- private int m_playerVersion; /* player version number obtained from InVersion message; e.g. 9 for Flash Player 9.0 */
-
- private boolean m_sourceListModified; /* deprecated; indicates m_source has changed since last
- * call to getSource().
- * WARNING: lock with synchronized (m_source) { ... }
- */
- private byte[] m_actions; /* deprecated */
- private String[] m_lastConstantPool; /* deprecated */
+ public static final String ARGUMENTS_MARKER = "$arguments"; //$NON-NLS-1$
+ public static final String SCOPE_CHAIN_MARKER = "$scopechain"; //$NON-NLS-1$
+
+ private static final DIsolate DEFAULT_ISOLATE = DIsolate.DEFAULT_ISOLATE;
+ private Isolate m_inIsolate = DEFAULT_ISOLATE;
+ private final Object m_inIsolateLock;
+ private final Object m_activeIsolateLock;
+ private boolean m_wideLines;
+ private DManagerIsolateState m_mainState;
+ private HashMap<Integer, DManagerIsolateState> m_isolateState;
+
+
+ class DManagerIsolateState {
+ public DSuspendInfo m_suspendInfo;
+ public DSwfInfo m_lastSwfInfo; /*
+ * hack for syncing swfinfo records with
+ * incoming InScript messages
+ */
+ public DVariable m_lastInGetVariable;/*
+ * hack for getVariable call to work
+ * with getters
+ */
+ public boolean m_attachChildren; /*
+ * hack for getVariable call to work
+ * with getters
+ */
+ public DVariable m_lastInCallFunction; /* hack for callFunction to work */
+ public DVariable m_lastInBinaryOp;
+ private boolean m_executingPlayerCode;
+ private FaultEvent m_faultEventDuringPlayerCodeExecution;
+
+ public final ArrayList<DLocation> m_breakpoints; /*
+ * WARNING: accessed
+ * from multiple threads
+ */
+ public final Map<Integer, DModule> m_source; /*
+ * WARNING: accessed from
+ * multiple threads
+ */
+ private final ArrayList<DSwfInfo> m_swfInfo; /*
+ * WARNING: accessed from
+ * multiple threads
+ */
+ private final ArrayList<DWatch> m_watchpoints; /*
+ * WARNING: accessed
+ * from multiple threads
+ */
- // SWF/SWD fetching and parsing
- private String m_uri;
- private byte[] m_swf; // latest swf obtained from get swf
- private byte[] m_swd; // latest swd obtained from get swd
+ /**
+ * The currently active stack frames.
+ */
+ public ArrayList<DStackContext> m_frames;
+
+ /**
+ * The stack frames that were active the last time the player was
+ * suspended.
+ */
+ public ArrayList<DStackContext> m_previousFrames;
- private boolean m_executingPlayerCode;
- private FaultEvent m_faultEventDuringPlayerCodeExecution;
+ /**
+ * A list of all known variables in the player. Stored as a mapping from
+ * an object's id to its DValue.
+ */
+ public Map<Long, DValue> m_values;
- private Map<String, String> m_options = new HashMap<String, String>(); // Player options that have been queried by OutGetOption, and come back via InOption
+ /**
+ * A list of all known variables in the player from the previous time
+ * the player was suspended. Stored as a mapping from an object's id to
+ * its DValue.
+ */
+ public Map<Long, DValue> m_previousValues;
+
+ public DManagerIsolateState() {
+ m_source = new HashMap<Integer, DModule>();
+ m_values = new HashMap<Long, DValue>();
+ m_previousValues = new HashMap<Long, DValue>();
+ m_frames = new ArrayList<DStackContext>();
+ m_previousFrames = new ArrayList<DStackContext>();
+ m_suspendInfo = null;
+ m_lastInCallFunction = null;
+ m_breakpoints = new ArrayList<DLocation>();
+ m_swfInfo = new ArrayList<DSwfInfo>();
+ m_watchpoints = new ArrayList<DWatch>();
+ m_suspendInfo = null;
+ m_lastInGetVariable = null;
+ m_attachChildren = true;
+ m_lastInCallFunction = null;
- public static final String ARGUMENTS_MARKER = "$arguments"; //$NON-NLS-1$
- public static final String SCOPE_CHAIN_MARKER = "$scopechain"; //$NON-NLS-1$
+ }
+ }
+
+ private DManagerIsolateState getIsolateState(int isolateId) {
+ if (isolateId == Isolate.DEFAULT_ID)
+ return m_mainState;
+
+ DManagerIsolateState isolateState = null;
+ if (!m_isolateState.containsKey(isolateId)) {
+ isolateState = new DManagerIsolateState();
+ m_isolateState.put(isolateId, isolateState);
+ } else
+ isolateState = m_isolateState.get(isolateId);
+ return isolateState;
+ }
- public DManager()
- {
+ public DManager() {
m_parms = new HashMap<String, String>();
- m_source = new HashMap<Integer, DModule>();
- m_breakpoints = new ArrayList<DLocation>();
- m_values = new HashMap<Long, DValue>();
- m_previousValues = new HashMap<Long, DValue>();
- m_frames = new ArrayList<DStackContext>();
- m_previousFrames = new ArrayList<DStackContext>();
- m_swfInfo = new ArrayList<DSwfInfo>();
- m_watchpoints = new ArrayList<DWatch>();
+
+ m_isolates = new HashMap<Integer, DIsolate>();
+ m_isolates.put(Isolate.DEFAULT_ID, DEFAULT_ISOLATE);
m_event = new LinkedList<DebugEvent>();
- m_suspendInfo = null;
m_sourceLocator = null;
-
- m_lastInGetVariable = null;
- m_attachChildren = true;
- m_lastInCallFunction = null;
m_squelchEnabled = false;
m_lastConstantPool = null;
- m_playerVersion = -1; // -1 => unknown
+ m_playerVersion = -1; // -1 => unknown
+ m_isolateState = new HashMap<Integer, DManagerIsolateState>();
+ m_mainState = new DManagerIsolateState();
+ m_isolateState.put(Isolate.DEFAULT_ID, m_mainState);
+ m_inIsolateLock = new Object();
+ m_activeIsolateLock = new Object();
+ m_wideLines = false;
+ }
+
+ public void setWideLines(boolean value) {
+ m_wideLines = value;
+ }
+
+ public String getURI() {
+ return m_uri;
+ }
+
+ public byte[] getSWF() {
+ return m_swf;
+ }
+
+ public byte[] getSWD() {
+ return m_swd;
+ }
+
+ public byte[] getActions() {
+ return m_actions;
}
- public String getURI() { return m_uri; }
- public byte[] getSWF() { return m_swf; }
- public byte[] getSWD() { return m_swd; }
- public byte[] getActions() { return m_actions; }
-
- /** Returns the Flash Player version number; e.g. 9 for Flash Player 9.0 */
- public int getVersion() { return m_playerVersion; }
-
- public SourceLocator getSourceLocator() { return m_sourceLocator; }
- public void setSourceLocator(SourceLocator sl) { m_sourceLocator = sl; }
+ /** Returns the Flash Player version number; e.g. 9 for Flash Player 9.0 */
+ public int getVersion() {
+ return m_playerVersion;
+ }
+
+ public SourceLocator getSourceLocator() {
+ return m_sourceLocator;
+ }
+
+ public void setSourceLocator(SourceLocator sl) {
+ m_sourceLocator = sl;
+ }
/**
- * If this feature is enabled then we do not attempt to attach
- * child variables to parents.
+ * If this feature is enabled then we do not attempt to attach child
+ * variables to parents.
*/
- public void enableChildAttach(boolean enable) { m_attachChildren = enable; }
+ public void enableChildAttach(boolean enable, int isolateId) {
+ getIsolateState(isolateId).m_attachChildren = enable;
+ }
// return/clear the last variable seen from an InGetVariable message
- public DVariable lastVariable() { return m_lastInGetVariable; }
- public void clearLastVariable() { m_lastInGetVariable = null; }
+ public DVariable lastVariable(int isolateId) {
+ return getIsolateState(isolateId).m_lastInGetVariable;
+ }
+
+ public void clearLastVariable(int isolateId) {
+ getIsolateState(isolateId).m_lastInGetVariable = null;
+ }
// return/clear the last variable seen from an InCallFunction message
- public DVariable lastFunctionCall() { return m_lastInCallFunction; }
- public void clearLastFunctionCall() { m_lastInCallFunction = null; }
+ public DVariable lastFunctionCall(int isolateId) {
+ return getIsolateState(isolateId).m_lastInCallFunction;
+ }
+
+ public void clearLastFunctionCall(int isolateId) {
+ getIsolateState(isolateId).m_lastInCallFunction = null;
+ }
// return/clear the last binary op result seen from an InBinaryOp message
- public DVariable lastBinaryOp() { return m_lastInBinaryOp; }
- public void clearLastBinaryOp() { m_lastInBinaryOp = null; }
+ public DVariable lastBinaryOp(int isolateId) {
+ return getIsolateState(isolateId).m_lastInBinaryOp;
+ }
+
+ public void clearLastBinaryOp(int isolateId) {
+ getIsolateState(isolateId).m_lastInBinaryOp = null;
+ }
/*
* Frees up any information we have kept about
*/
- void freeCaches()
- {
- clearFrames();
- freeValueCache();
+ void freeCaches(int isolateId) {
+ clearFrames(isolateId);
+ freeValueCache(isolateId);
}
- void freeValueCache()
- {
- m_previousValues = m_values;
- m_values = new HashMap<Long, DValue>();
+ void freeValueCache(int isolateId) {
+ DManagerIsolateState state = getIsolateState(isolateId);
+ state.m_previousValues = state.m_values;
+ state.m_values = new HashMap<Long, DValue>();
- // mark all frames as stale
- int size = getFrameCount();
- for(int i=0; i<size; i++)
- getFrame(i).markStale();
+ int size = getFrameCount(isolateId);
+ for (int i = 0; i < size; i++)
+ getFrame(i, isolateId).markStale();
}
// continuing our execution
- void continuing()
- {
- freeCaches();
- m_suspendInfo = null;
+ void continuing(int isolateId) {
+ freeCaches(isolateId);
+ getIsolateState(isolateId).m_suspendInfo = null;
}
/**
* Variables
*/
- DValue getOrCreateValue(long id)
- {
- DValue v = getValue(id);
- if (v == null)
- {
- v = new DValue(id);
- putValue(id, v);
+ DValue getOrCreateValue(long id, int isolateId) {
+ DValue v = getValue(id, isolateId);
+ if (v == null) {
+ v = new DValue(id, isolateId);
+ putValue(id, v, isolateId);
}
return v;
}
- // Simple DSwfInfo getters
- public DSwfInfo[] getSwfInfos()
- {
- synchronized (m_swfInfo)
- {
- return m_swfInfo.toArray( new DSwfInfo[m_swfInfo.size()] );
+ public DSwfInfo[] getSwfInfos(int isolateId) {
+ ArrayList<DSwfInfo> swfInfos = getIsolateState(isolateId).m_swfInfo;
+ synchronized (swfInfos) {
+ return swfInfos.toArray(new DSwfInfo[swfInfos.size()]);
}
}
- public DSwfInfo getSwfInfo(int at)
- {
- synchronized (m_swfInfo)
- {
- return m_swfInfo.get(at);
+ public DSwfInfo getSwfInfo(int at, int isolateId) {
+ ArrayList<DSwfInfo> swfInfos = getIsolateState(isolateId).m_swfInfo;
+ synchronized (swfInfos) {
+ return swfInfos.get(at);
}
}
- public int getSwfInfoCount()
- {
- synchronized (m_swfInfo)
- {
- return m_swfInfo.size();
+ public int getSwfInfoCount(int isolateId) {
+ ArrayList<DSwfInfo> swfInfos = getIsolateState(isolateId).m_swfInfo;
+ synchronized (swfInfos) {
+ return swfInfos.size();
}
}
/**
- * Obtains a SwfInfo object at the given index or if one
- * doesn't yet exist at that location, creates a new empty
- * one there and returns it.
+ * Obtains a SwfInfo object at the given index or if one doesn't yet exist
+ * at that location, creates a new empty one there and returns it.
*/
- DSwfInfo getOrCreateSwfInfo(int at)
- {
- synchronized (m_swfInfo)
- {
- DSwfInfo i = (at > -1 && at < getSwfInfoCount()) ? getSwfInfo(at) : null;
- if (i == null)
- {
+ DSwfInfo getOrCreateSwfInfo(int at, int isolateId) {
+ ArrayList<DSwfInfo> swfInfos = getIsolateState(isolateId).m_swfInfo;
+ synchronized (swfInfos) {
+ DSwfInfo i = (at > -1 && at < getSwfInfoCount(isolateId)) ? getSwfInfo(
+ at, isolateId) : null;
+ if (i == null) {
// are we above water
at = (at < 0) ? 0 : at;
// fill all the gaps with null; really shouldn't be any...
- while(at > m_swfInfo.size())
- m_swfInfo.add(null);
+ while (at >= swfInfos.size())
+ swfInfos.add(null);
- i = new DSwfInfo(at);
- m_swfInfo.add(at, i);
+ i = new DSwfInfo(at, isolateId);
+ swfInfos.set(at, i);
}
return i;
}
}
/**
- * Get the most recently active swfInfo object.
- * We define active as the most recently seen swfInfo
+ * Get the most recently active swfInfo object. We define active as the most
+ * recently seen swfInfo
*/
- DSwfInfo getActiveSwfInfo()
- {
- int count = getSwfInfoCount();
+ DSwfInfo getActiveSwfInfo(int isolateId) {
+ int count = getSwfInfoCount(isolateId);
// pick up the last one seen
- DSwfInfo swf = m_lastSwfInfo;
+ DSwfInfo swf = getIsolateState(isolateId).m_lastSwfInfo;
// still don't have one then get or create the most recent one
// works if count = 0
if (swf == null)
- swf = getOrCreateSwfInfo(count-1);
+ swf = getOrCreateSwfInfo(count - 1, isolateId);
- if (swf.hasAllSource())
- {
+ if (swf.hasAllSource()) {
// already full so create a new one on the end
- swf = getOrCreateSwfInfo(count);
+ swf = getOrCreateSwfInfo(count, isolateId);
}
return swf;
}
/**
- * Walk the list of scripts and add them to our swfInfo object
- * This method may be called when min/max are zero and the swd
- * has not yet fully loaded in the player or it could be called
- * before we have all the scripts.
+ * Walk the list of scripts and add them to our swfInfo object This method
+ * may be called when min/max are zero and the swd has not yet fully loaded
+ * in the player or it could be called before we have all the scripts.
*/
- void tieScriptsToSwf(DSwfInfo info)
- {
- if (!info.hasAllSource())
- {
+ void tieScriptsToSwf(DSwfInfo info, int isolateId) {
+ if (!info.hasAllSource()) {
int min = info.getFirstSourceId();
int max = info.getLastSourceId();
-// System.out.println("attaching scripts "+min+"-"+max+" to "+info.getUrl());
- for(int i=min; i<=max; i++)
- {
- DModule m = getSource(i);
- if (m == null)
- {
+ // System.out.println("attaching scripts "+min+"-"+max+" to "+info.getUrl());
+ for (int i = min; i <= max; i++) {
+ DModule m = getSource(i, isolateId);
+ if (m == null) {
// this is ok, it means the scripts are coming...
- }
- else
- {
+ } else {
info.addSource(i, m);
}
}
@@ -316,35 +431,39 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
/**
* Record a new source file.
- * @param name filename in "basepath;package;filename" format
- * @param swfIndex the index of the SWF with which this source is associated,
- * or -1 is we don't know
+ *
+ * @param name
+ * filename in "basepath;package;filename" format
+ * @param swfIndex
+ * the index of the SWF with which this source is associated, or
+ * -1 is we don't know
* @return true if our list of source files was modified, or false if we
- * already knew about that particular source file.
+ * already knew about that particular source file.
*/
- private boolean putSource(int swfIndex, int moduleId, int bitmap, String name, String text)
- {
- synchronized (m_source)
- {
+ private boolean putSource(int swfIndex, int moduleId, int bitmap,
+ String name, String text, int isolateId) {
+ // if isolateIndex is not -1, augment swfIndex and moduleId with isolate
+ // info.
+ Map<Integer, DModule> source = getIsolateState(isolateId).m_source;
+ synchronized (source) {
// if we haven't already recorded this script then do so.
- if (!m_source.containsKey(moduleId))
- {
- DModule s = new DModule(this, moduleId, bitmap, name, text);
+ if (!source.containsKey(moduleId)) {
+ DModule s = new DModule(this, moduleId, bitmap, name, text, isolateId);
- // put source in our large pool
- m_source.put(moduleId, s);
+ // put source in our large pool
+ source.put(moduleId, s);
- // put the source in the currently active swf
- DSwfInfo swf;
- if (swfIndex == -1) // caller didn't tell us what swf thi is for
- swf = getActiveSwfInfo(); // ... so guess
+ // put the source in the currently active swf
+ DSwfInfo swf;
+ if (swfIndex == -1) // caller didn't tell us what swf thi is for
+ swf = getActiveSwfInfo(isolateId); // ... so guess
else
- swf = getOrCreateSwfInfo(swfIndex);
+ swf = getOrCreateSwfInfo(swfIndex, isolateId);
- swf.addSource(moduleId, s);
+ swf.addSource(moduleId, s);
return true;
- }
+ }
return false;
}
@@ -352,237 +471,246 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
/**
* Remove our record of a particular source file.
- * @param id the id of the file to forget about.
- * @return true if source file was removed; false if we didn't know about
- * it to begin with.
+ *
+ * @param id
+ * the id of the file to forget about.
+ * @return true if source file was removed; false if we didn't know about it
+ * to begin with.
*/
- private boolean removeSource(int id)
- {
- synchronized (m_source)
- {
- try
- {
- m_source.remove(id);
- }
- catch(Exception e)
- {
+ private boolean removeSource(int id, int isolateId) {
+ Map<Integer, DModule> source = getIsolateState(isolateId).m_source;
+ synchronized (source) {
+ try {
+ source.remove(id);
+ } catch (Exception e) {
return false;
}
return true;
}
}
- public DModule getSource(int id)
- {
- synchronized (m_source)
- {
- return m_source.get(id);
+ public DModule getSource(int id, int isolateId) {
+ Map<Integer, DModule> source = getIsolateState(isolateId).m_source;
+ synchronized (source) {
+ return source.get(id);
}
}
// @deprecated
- public DModule[] getSources()
- {
- synchronized (m_source)
- {
+ public DModule[] getSources() {
+ Map<Integer, DModule> source = getIsolateState(Isolate.DEFAULT_ID).m_source;
+ synchronized (source) {
m_sourceListModified = false;
/* find out the size of the array */
- int count = m_source.size();
+ int count = source.size();
DModule[] ar = new DModule[count];
count = 0;
- for (DModule sf: m_source.values())
+ for (DModule sf : source.values())
ar[count++] = sf;
return ar;
}
}
// @deprecated
- boolean sourceListModified()
- {
- synchronized (m_source)
- {
+ boolean sourceListModified() {
+ Map<Integer, DModule> source = getIsolateState(Isolate.DEFAULT_ID).m_source;
+ synchronized (source) {
return m_sourceListModified;
}
}
- public DValue getValue(long id)
- {
- DValue v = m_values.get(id);
- return v;
+ public DValue getValue(long id, int isolateId) {
+ return getIsolateState(isolateId).m_values.get(id);
}
/**
- * Returns the previous value object for the given id -- that is, the value that that
- * object had the last time the player was suspended. Never requests it from the
- * player (because it can't, of course). Returns <code>null</code> if we don't have
- * a value for that id.
+ * Returns the previous value object for the given id -- that is, the value
+ * that that object had the last time the player was suspended. Never
+ * requests it from the player (because it can't, of course). Returns
+ * <code>null</code> if we don't have a value for that id.
*/
- public DValue getPreviousValue(long id)
- {
- return m_previousValues.get(id);
+ public DValue getPreviousValue(long id, int isolateId) {
+ return getIsolateState(isolateId).m_previousValues.get(id);
}
- void putValue(long id, DValue v)
- {
- if (id != Value.UNKNOWN_ID)
- {
- m_values.put(id, v);
+ void putValue(long id, DValue v, int isolateId) {
+ if (id != Value.UNKNOWN_ID) {
+ getIsolateState(isolateId).m_values.put(id, v);
}
}
- DValue removeValue(long id)
- {
- return m_values.remove((int)id);
+ DValue removeValue(long id, int isolateId) {
+ return getIsolateState(isolateId).m_values.remove((int)id);
}
- void addVariableMember(long parentId, DVariable child)
- {
- DValue parent = getValue(parentId);
- addVariableMember(parent, child);
+ void addVariableMember(long parentId, DVariable child, int isolateId) {
+ DValue parent = getValue(parentId, isolateId);
+ addVariableMember(parent, child, isolateId);
}
- void addVariableMember(DValue parent, DVariable child)
- {
- if (m_attachChildren)
- {
- // There are certain situations when the Flash player will send us more
- // than one variable or getter with the same name. Basically, when a
- // subclass implements (or overrides) something that was also declared in a
+ void addVariableMember(DValue parent, DVariable child, int isolateId) {
+ if (getIsolateState(isolateId).m_attachChildren) {
+ // There are certain situations when the Flash player will send us
+ // more
+ // than one variable or getter with the same name. Basically, when a
+ // subclass implements (or overrides) something that was also
+ // declared in a
// superclass, then we'll see that variable or getter in both the
// superclass and the subclass.
//
- // Here are a few situations where that affects the debugger in different
+ // Here are a few situations where that affects the debugger in
+ // different
// ways:
//
- // 1. When a class implements an interface, the class instance actually has
- // *two* members for each implemented function: One which is public and
- // represents the implementation function, and another which is internal
- // to the interface, and represents the declaration of the function.
- // Both of these come in to us. In the UI, the one we want to show is
- // the public one. They come in in random order (they are stored in a
- // hash table in the VM), so we don't know which one will come first.
+ // 1. When a class implements an interface, the class instance
+ // actually has
+ // *two* members for each implemented function: One which is public
+ // and
+ // represents the implementation function, and another which is
+ // internal
+ // to the interface, and represents the declaration of the function.
+ // Both of these come in to us. In the UI, the one we want to show
+ // is
+ // the public one. They come in in random order (they are stored in
+ // a
+ // hash table in the VM), so we don't know which one will come
+ // first.
//
- // 2. When a superclass has a private member "m", and a subclass has its own
- // private member with the same name "m", we will receive both of them.
- // (They are scoped by different packages.) In this case, the first one
- // the player sent us is the one from the subclass, and that is the one
- // we want to display in the debugger.
+ // 2. When a superclass has a private member "m", and a subclass has
+ // its own
+ // private member with the same name "m", we will receive both of
+ // them.
+ // (They are scoped by different packages.) In this case, the first
+ // one
+ // the player sent us is the one from the subclass, and that is the
+ // one
+ // we want to display in the debugger.
//
- // The following logic correctly deals with all variations of those cases.
- if (parent != null)
- {
- DVariable existingChildWithSameName = parent.findMember(child.getName());
- if (existingChildWithSameName != null)
- {
+ // The following logic correctly deals with all variations of those
+ // cases.
+ if (parent != null) {
+ DVariable existingChildWithSameName = parent.findMember(child
+ .getName());
+ if (existingChildWithSameName != null) {
int existingScope = existingChildWithSameName.getScope();
int newScope = child.getScope();
- if (existingScope == VariableAttribute.NAMESPACE_SCOPE && newScope == VariableAttribute.PUBLIC_SCOPE)
- {
- // This is the case described above where a class implements an interface,
- // so that class's definition includes both a namespace-scoped declaration
- // and a public declaration, in random order; in this case, the
- // namespace-scoped declaration came first. We want to use the public
+ if (existingScope == VariableAttribute.NAMESPACE_SCOPE
+ && newScope == VariableAttribute.PUBLIC_SCOPE) {
+ // This is the case described above where a class
+ // implements an interface,
+ // so that class's definition includes both a
+ // namespace-scoped declaration
+ // and a public declaration, in random order; in this
+ // case, the
+ // namespace-scoped declaration came first. We want to
+ // use the public
// declaration.
parent.addMember(child);
- }
- else if (existingScope == VariableAttribute.PUBLIC_SCOPE && newScope == VariableAttribute.NAMESPACE_SCOPE)
- {
+ } else if (existingScope == VariableAttribute.PUBLIC_SCOPE
+ && newScope == VariableAttribute.NAMESPACE_SCOPE) {
// One of two things happened here:
//
- // 1. This is the case described above where a class implements an interface,
- // so that class's definition includes both a namespace-scoped declaration
- // and a public declaration, in random order; in this case, the
- // public declaration came first. It is tempting to use the public
- // member in this case, but there is a catch...
- // 2. It might be more complicated than that: Perhaps there is interface I,
- // and class C1 implements I, but class C2 extends C1, and overrides
- // one of the members of I that was already implemented by C1. In this
- // case, the public declaration from C2 came first, but now we are seeing
- // a namespace-scoped declaration in C1. We need to record that the
- // member is public, but we also need to record that it is a member
- // of the base class, not just a member of the superclass.
+ // 1. This is the case described above where a class
+ // implements an interface,
+ // so that class's definition includes both a
+ // namespace-scoped declaration
+ // and a public declaration, in random order; in this
+ // case, the
+ // public declaration came first. It is tempting to use
+ // the public
+ // member in this case, but there is a catch...
+ // 2. It might be more complicated than that: Perhaps
+ // there is interface I,
+ // and class C1 implements I, but class C2 extends C1,
+ // and overrides
+ // one of the members of I that was already implemented
+ // by C1. In this
+ // case, the public declaration from C2 came first, but
+ // now we are seeing
+ // a namespace-scoped declaration in C1. We need to
+ // record that the
+ // member is public, but we also need to record that it
+ // is a member
+ // of the base class, not just a member of the
+ // superclass.
//
- // The easiest way to deal with both cases is to use the child that came from
+ // The easiest way to deal with both cases is to use the
+ // child that came from
// the superclass, but to change its scope to public.
child.makePublic();
parent.addMember(child);
- }
- else if (existingScope != VariableAttribute.PRIVATE_SCOPE && existingScope == newScope)
- {
- // This is a public, protected, internal, or namespace-scoped member which
- // was defined in a base class and overridden in a subclass. We want to
- // use the member from the base class, to that the debugger knows where the
+ } else if (existingScope != VariableAttribute.PRIVATE_SCOPE
+ && existingScope == newScope) {
+ // This is a public, protected, internal, or
+ // namespace-scoped member which
+ // was defined in a base class and overridden in a
+ // subclass. We want to
+ // use the member from the base class, to that the
+ // debugger knows where the
// variable was actually defined.
parent.addMember(child);
- }
- else if (existingScope == VariableAttribute.PRIVATE_SCOPE && existingScope == newScope)
- {
+ } else if (existingScope == VariableAttribute.PRIVATE_SCOPE
+ && existingScope == newScope) {
parent.addInheritedPrivateMember(child);
}
- }
- else
- {
+ } else {
parent.addMember(child);
}
}
// put child in the registry if it has an id and not already there
DValue childValue = (DValue) child.getValue();
long childId = childValue.getId();
- if (childId != Value.UNKNOWN_ID)
- {
- DValue existingValue = getValue(childId);
- if (existingValue != null)
- {
- assert existingValue == childValue; // TODO is this right? what about getters?
- }
- else
- {
- putValue(childId, childValue);
+ if (childId != Value.UNKNOWN_ID) {
+ DValue existingValue = getValue(childId, isolateId);
+ if (existingValue != null) {
+ assert existingValue == childValue; // TODO is this right?
+ // what about getters?
+ } else {
+ putValue(childId, childValue, isolateId);
}
}
}
}
// TODO is this right?
- void addVariableMember(long parentId, DVariable child, long doubleAsId)
- {
- addVariableMember(parentId, child);
+ void addVariableMember(long parentId, DVariable child, long doubleAsId,
+ int isolateId) {
+ addVariableMember(parentId, child, isolateId);
// double book the child under another id
- if (m_attachChildren)
- putValue(doubleAsId, (DValue) child.getValue());
+ if (getIsolateState(isolateId).m_attachChildren)
+ putValue(doubleAsId, (DValue) child.getValue(), isolateId);
}
- // @deprecated last pool that was read
- public String[] getConstantPool() { return m_lastConstantPool; }
+ // @deprecated last pool that was read
+ public String[] getConstantPool() {
+ return m_lastConstantPool;
+ }
/**
* Breakpoints
*/
- public DLocation getBreakpoint(int id)
- {
- synchronized (m_breakpoints)
- {
+ public DLocation getBreakpoint(int id, int isolateId) {
+ ArrayList<DLocation> breakpoints = getIsolateState(isolateId).m_breakpoints;
+ synchronized (breakpoints) {
DLocation loc = null;
- int which = findBreakpoint(id);
+ int which = findBreakpoint(id, isolateId);
if (which > -1)
- loc = m_breakpoints.get(which);
+ loc = breakpoints.get(which);
return loc;
}
}
- int findBreakpoint(int id)
- {
- synchronized (m_breakpoints)
- {
+ int findBreakpoint(int id, int isolateId) {
+ ArrayList<DLocation> breakpoints = getIsolateState(isolateId).m_breakpoints;
+ synchronized (breakpoints) {
int which = -1;
- int size = m_breakpoints.size();
- for(int i=0; which < 0 && i<size; i++)
- {
- DLocation l = m_breakpoints.get(i);
+ int size = breakpoints.size();
+ for (int i = 0; which < 0 && i < size; i++) {
+ DLocation l = breakpoints.get(i);
if (l.getId() == id)
which = i;
}
@@ -590,68 +718,83 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
}
}
- DLocation removeBreakpoint(int id)
- {
- synchronized (m_breakpoints)
- {
+ DLocation removeBreakpoint(int id, int isolateId) {
+ ArrayList<DLocation> breakpoints = getIsolateState(isolateId).m_breakpoints;
+ synchronized (breakpoints) {
DLocation loc = null;
- int which = findBreakpoint(id);
- if (which > -1)
- {
- loc = m_breakpoints.get(which);
- m_breakpoints.remove(which);
+ int which = findBreakpoint(id, isolateId);
+ if (which > -1) {
+ loc = breakpoints.get(which);
+ breakpoints.remove(which);
}
return loc;
}
}
- void addBreakpoint(int id, DLocation l)
- {
- synchronized (m_breakpoints)
- {
- m_breakpoints.add(l);
+ void addBreakpoint(int id, DLocation l, int isolateId) {
+ ArrayList<DLocation> breakpoints = getIsolateState(isolateId).m_breakpoints;
+ synchronized (breakpoints) {
+ breakpoints.add(l);
}
}
- public DLocation[] getBreakpoints()
- {
- synchronized (m_breakpoints)
- {
- return m_breakpoints.toArray(new DLocation[m_breakpoints.size()]);
+ public DLocation[] getBreakpoints(int isolateId) {
+ ArrayList<DLocation> breakpoints = getIsolateState(isolateId).m_breakpoints;
+ synchronized (breakpoints) {
+ return breakpoints.toArray(new DLocation[breakpoints.size()]);
}
}
/**
* Watchpoints
*/
- public DWatch getWatchpoint(int at) { synchronized (m_watchpoints) { return m_watchpoints.get(at); } }
- public int getWatchpointCount() { synchronized (m_watchpoints) { return m_watchpoints.size(); } }
- public DWatch[] getWatchpoints() { synchronized (m_watchpoints) { return m_watchpoints.toArray( new DWatch[m_watchpoints.size()] ); } }
+ public DWatch getWatchpoint(int at, int isolateId) {
+ DManagerIsolateState state = getIsolateState(isolateId);
+ synchronized (state.m_watchpoints) {
+ return state.m_watchpoints.get(at);
+ }
+ }
- boolean addWatchpoint(DWatch w) { synchronized (m_watchpoints) { return m_watchpoints.add(w); } }
+ public int getWatchpointCount(int isolateId) {
+ DManagerIsolateState state = getIsolateState(isolateId);
+ synchronized (state.m_watchpoints) {
+ return state.m_watchpoints.size();
+ }
+ }
- DWatch removeWatchpoint(int tag)
- {
- synchronized (m_watchpoints)
- {
+ public DWatch[] getWatchpoints(int isolateId) {
+ DManagerIsolateState state = getIsolateState(isolateId);
+ synchronized (state.m_watchpoints) {
+ return state.m_watchpoints.toArray(new DWatch[state.m_watchpoints.size()]);
+ }
+ }
+
+ boolean addWatchpoint(DWatch w, int isolateId) {
+ ArrayList<DWatch> lockObject = getIsolateState(isolateId).m_watchpoints;
+ synchronized (lockObject) {
+ return lockObject.add(w);
+ }
+ }
+
+ DWatch removeWatchpoint(int tag, int isolateId) {
+ ArrayList<DWatch> lockObject = getIsolateState(isolateId).m_watchpoints;
+ synchronized (lockObject) {
DWatch w = null;
- int at = findWatchpoint(tag);
+ int at = findWatchpoint(tag, isolateId);
if (at > -1)
- w = m_watchpoints.remove(at);
+ w = lockObject.remove(at);
return w;
}
}
- int findWatchpoint(int tag)
- {
- synchronized (m_watchpoints)
- {
+ int findWatchpoint(int tag, int isolateId) {
+ ArrayList<DWatch> lockObject = getIsolateState(isolateId).m_watchpoints;
+ synchronized (lockObject) {
int at = -1;
- int size = getWatchpointCount();
- for(int i=0; i<size && at<0; i++)
- {
- DWatch w = getWatchpoint(i);
+ int size = getWatchpointCount(isolateId);
+ for (int i = 0; i < size && at < 0; i++) {
+ DWatch w = getWatchpoint(i, isolateId);
if (w.getTag() == tag)
at = i;
}
@@ -660,28 +803,140 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
}
/**
+ * Isolates
+ */
+ public DIsolate getIsolate(int at) {
+
+ if (at == Isolate.DEFAULT_ID)
+ return (DIsolate) DEFAULT_ISOLATE;
+
+ synchronized (m_isolates) {
+ return m_isolates.get(at);
+ }
+ }
+
+ public DIsolate getOrCreateIsolate(int at) {
+ synchronized (m_isolates) {
+ if (m_isolates.containsKey(at)) {
+ return m_isolates.get(at);
+ } else {
+ DIsolate isolate = new DIsolate(at);
+ m_isolates.put(at, isolate);
+ return isolate;
+ }
+ }
+ }
+
+ public int getIsolateCount() {
+ synchronized (m_isolates) {
+ return m_isolates.size();
+ }
+ }
+
+ public DIsolate[] getIsolates() {
+ synchronized (m_isolates) {
+ return m_isolates.values().toArray(new DIsolate[m_isolates.size()]);
+ }
+ }
+
+ boolean addIsolate(DIsolate t) {
+ synchronized (m_isolates) {
+ m_isolates.put(t.getId(), t);
+ return true;
+ }
+ }
+
+ void clearIsolates() {
+ synchronized (m_isolates) {
+ m_isolates.clear();
+ }
+ }
+
+ DIsolate removeIsolate(int id) {
+ synchronized (m_isolates) {
+ DIsolate t = null;
+ int at = findIsolate(id);
+ if (at > -1)
+ t = m_isolates.remove(at);
+ return t;
+ }
+ }
+
+ int findIsolate(int id) {
+ synchronized (m_isolates) {
+ if (m_isolates.containsKey(id))
+ return id;
+ else
+ return -1;
+ }
+ }
+
+ void setActiveIsolate(Isolate t) {
+ synchronized (m_activeIsolateLock) {
+ if (t == null) {
+ m_activeIsolate = DEFAULT_ISOLATE;
+ } else
+ m_activeIsolate = t;
+ }
+ }
+
+ Isolate getActiveIsolate() {
+ synchronized (m_activeIsolateLock) {
+ return m_activeIsolate;
+ }
+ }
+
+
+ void setInIsolate(Isolate t) {
+ synchronized (m_inIsolateLock) {
+ if (t == null) {
+ m_inIsolate = DEFAULT_ISOLATE;
+ } else
+ m_inIsolate = t;
+ }
+ }
+
+ Isolate getInIsolate() {
+ synchronized (m_inIsolateLock) {
+ return m_inIsolate;
+ }
+ }
+
+ Isolate getDefaultIsolate() {
+ return DEFAULT_ISOLATE;
+ }
+
+
+ /**
* Frame stack management related stuff
+ *
* @return true if we added this frame; false if we ignored it
*/
- boolean addFrame(DStackContext ds)
- {
- m_frames.add(ds);
+ boolean addFrame(DStackContext ds, int isolateId) {
+ getIsolateState(isolateId).m_frames.add(ds);
return true;
}
- void clearFrames()
- {
- if (m_frames.size() > 0)
- m_previousFrames = m_frames;
- m_frames = new ArrayList<DStackContext>();
+ void clearFrames(int isolateId) {
+ if (getIsolateState(isolateId).m_frames.size() > 0)
+ getIsolateState(isolateId).m_previousFrames = getIsolateState(isolateId).m_frames;
+ getIsolateState(isolateId).m_frames = new ArrayList<DStackContext>();
}
- public DStackContext getFrame(int at) { return m_frames.get(at);}
- public int getFrameCount() { return m_frames.size();}
- public DStackContext[] getFrames() { return m_frames.toArray( new DStackContext[m_frames.size()] ); }
+ public DStackContext getFrame(int at, int isolateId) {
+ return getIsolateState(isolateId).m_frames.get(at);
+ }
+
+ public int getFrameCount(int isolateId) {
+ return getIsolateState(isolateId).m_frames.size();
+ }
- private boolean stringsEqual(String s1, String s2)
- {
+ public DStackContext[] getFrames(int isolateId) {
+ ArrayList<DStackContext> frames = getIsolateState(isolateId).m_frames;
+ return frames.toArray(new DStackContext[frames.size()]);
+ }
+
+ private boolean stringsEqual(String s1, String s2) {
if (s1 == null)
return s2 == null;
else
@@ -691,34 +946,41 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
/**
* Correlates the old list of stack frames, from the last time the player
* was suspended, with the new list of stack frames, attempting to guess
- * which frames correspond to each other. This is done so that
+ * which frames correspond to each other. This is done so that
* Variable.hasValueChanged() can work correctly for local variables.
*/
- private void mapOldFramesToNew() {
- int oldSize = m_previousFrames.size();
- int newSize = m_frames.size();
+ private void mapOldFramesToNew(int isolateId) {
+ ArrayList<DStackContext> previousFrames = null;
+ ArrayList<DStackContext> frames = null;
+ Map<Long, DValue> previousValues = null;
+
+ previousFrames = getIsolateState(isolateId).m_previousFrames;
+ frames = getIsolateState(isolateId).m_frames;
+ previousValues = getIsolateState(isolateId).m_previousValues;
+
+ int oldSize = previousFrames.size();
+ int newSize = frames.size();
// discard all old frames (we will restore some of them below)
DValue[] oldFrames = new DValue[oldSize];
for (int depth = 0; depth < oldSize; depth++) {
- oldFrames[depth] = (DValue) m_previousValues.remove(Value.BASE_ID - depth);
+ oldFrames[depth] = (DValue) previousValues.remove(Value.BASE_ID
+ - depth);
}
// Start at the end of the stack (the stack frame farthest from the
// current one), and try to match up stack frames
- int oldDepth = oldSize-1;
- int newDepth = newSize-1;
- while (oldDepth >= 0 && newDepth >= 0)
- {
- DStackContext oldFrame = m_previousFrames.get(oldDepth);
- DStackContext newFrame = m_frames.get(newDepth);
- if (oldFrame != null && newFrame != null)
- {
- if (stringsEqual(oldFrame.getCallSignature(), newFrame.getCallSignature()))
- {
+ int oldDepth = oldSize - 1;
+ int newDepth = newSize - 1;
+ while (oldDepth >= 0 && newDepth >= 0) {
+ DStackContext oldFrame = previousFrames.get(oldDepth);
+ DStackContext newFrame = frames.get(newDepth);
+ if (oldFrame != null && newFrame != null) {
+ if (stringsEqual(oldFrame.getCallSignature(),
+ newFrame.getCallSignature())) {
DValue frame = oldFrames[oldDepth];
if (frame != null)
- m_previousValues.put(Value.BASE_ID - newDepth, frame);
+ previousValues.put(Value.BASE_ID - newDepth, frame);
}
}
oldDepth--;
@@ -727,62 +989,72 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
}
/**
- * Get function is only supported in players that
- * recognize the squelch message.
+ * Get function is only supported in players that recognize the squelch
+ * message.
*/
- public boolean isGetSupported()
- {
+ public boolean isGetSupported() {
return m_squelchEnabled;
}
+
/**
- * Returns a suspend information on
- * why the Player has suspended execution.
+ * Returns a suspend information on why the Player has suspended execution.
+ *
* @return see SuspendReason
*/
- public DSuspendInfo getSuspendInfo()
- {
- return m_suspendInfo;
+ public DSuspendInfo getSuspendInfo(int isolateId) {
+ if (m_isolateState.containsKey(isolateId)) {
+ return m_isolateState.get(isolateId).m_suspendInfo;
+ }
+ return null;
+ }
+
+ public ArrayList<SwfInfo> getIsolateSwfList() {
+ ArrayList<SwfInfo> result = new ArrayList<SwfInfo>();
+
+ for (DManagerIsolateState state : m_isolateState.values()) {
+ if (state.m_swfInfo != null) {
+ result.addAll(state.m_swfInfo);
+ }
+ }
+
+ return result;
}
/**
* Event management related stuff
*/
- public int getEventCount()
- {
- synchronized (m_event) { return m_event.size(); }
+ public int getEventCount() {
+ synchronized (m_event) {
+ return m_event.size();
+ }
}
/**
* Get an object on which callers can call wait(), in order to wait until
* something happens.
- *
+ *
* Note: The object will be signalled when EITHER of the following happens:
- * (1) An event is added to the event queue;
- * (2) The network connection is broken (and thus there will be no more events).
- *
+ * (1) An event is added to the event queue; (2) The network connection is
+ * broken (and thus there will be no more events).
+ *
* @return an object on which the caller can call wait()
*/
- public Object getEventNotifier()
- {
+ public Object getEventNotifier() {
return m_event;
}
- public DebugEvent nextEvent()
- {
+ public DebugEvent nextEvent() {
DebugEvent s = null;
- synchronized (m_event)
- {
+ synchronized (m_event) {
if (m_event.size() > 0)
s = m_event.removeFirst();
}
return s;
}
- public synchronized void addEvent(DebugEvent e)
- {
- synchronized (m_event)
- {
+ public synchronized void addEvent(DebugEvent e) {
+ synchronized (m_event) {
m_event.add(e);
m_event.notifyAll(); // wake up listeners (see getEventNotifier())
}
@@ -791,954 +1063,1116 @@ public class DManager implements DProtocolNotifierIF, SourceLocator
/**
* Issued when the socket connection to the player is cut
*/
- public void disconnected()
- {
- synchronized (m_event)
- {
+ public void disconnected() {
+ synchronized (m_event) {
m_event.notifyAll(); // see getEventNotifier()
}
}
/**
- * This is the core routine for decoding incoming messages and deciding what should be
- * done with them. We have registered ourself with DProtocol to be notified when any
- * incoming messages have been received.
- *
- * It is important to note that we should not rely on the contents of the message
- * since it may be reused after we exit this method.
+ * This is the core routine for decoding incoming messages and deciding what
+ * should be done with them. We have registered ourself with DProtocol to be
+ * notified when any incoming messages have been received.
+ *
+ * It is important to note that we should not rely on the contents of the
+ * message since it may be reused after we exit this method.
*/
- public void messageArrived(DMessage msg, DProtocol which)
- {
- /* at this point we just open up a big switch statement and walk through all possible cases */
+ public void messageArrived(DMessage msg, DProtocol which) {
+ /*
+ * at this point we just open up a big switch statement and walk through
+ * all possible cases
+ */
int type = msg.getType();
-// System.out.println("manager msg = "+DMessage.inTypeName(type));
+ // System.out.println("manager msg = "+DMessage.inTypeName(type));
+ int inIsolateId = getInIsolate() != null ? getInIsolate().getId()
+ : Isolate.DEFAULT_ID;
+ if (inIsolateId != Isolate.DEFAULT_ID) {
+ msg.setTargetIsolate(inIsolateId);
+ }
+ switch (type) {
+ case DMessage.InVersion: {
+ long ver = msg.getDWord();
+ m_playerVersion = (int) ver;
+
+ // Newer players will send another byte, which is the pointer size
+ // that is used by the player (in bytes).
+ int pointerSize;
+ if (msg.getRemaining() >= 1)
+ pointerSize = msg.getByte();
+ else
+ pointerSize = 4;
+ DMessage.setSizeofPtr(pointerSize);
+ break;
+ }
- switch(type)
- {
- case DMessage.InVersion:
- {
- long ver = msg.getDWord();
- m_playerVersion = (int)ver;
-
- // Newer players will send another byte, which is the pointer size
- // that is used by the player (in bytes).
- int pointerSize;
- if (msg.getRemaining() >= 1)
- pointerSize = msg.getByte();
- else
- pointerSize = 4;
- DMessage.setSizeofPtr(pointerSize);
- break;
- }
-
- case DMessage.InErrorExecLimit:
- {
- handleFaultEvent(new RecursionLimitFault());
- break;
- }
+ case DMessage.InErrorExecLimit: {
+ handleFaultEvent(new RecursionLimitFault(msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorWith:
- {
- handleFaultEvent(new InvalidWithFault());
- break;
- }
+ case DMessage.InErrorWith: {
+ handleFaultEvent(new InvalidWithFault(msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorProtoLimit:
- {
- handleFaultEvent(new ProtoLimitFault());
- break;
- }
+ case DMessage.InErrorProtoLimit: {
+ handleFaultEvent(new ProtoLimitFault(msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorURLOpen:
- {
- String url = msg.getString();
- handleFaultEvent(new InvalidURLFault(url));
- break;
- }
+ case DMessage.InErrorURLOpen: {
+// String url = msg.getString();
+// handleFaultEvent(new InvalidURLFault(url, msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorTarget:
- {
- String name = msg.getString();
- handleFaultEvent(new InvalidTargetFault(name));
- break;
- }
+ case DMessage.InErrorTarget: {
+// String name = msg.getString();
+// handleFaultEvent(new InvalidTargetFault(name, msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorException:
- {
- long offset = msg.getDWord();
- // As of FP9, the player will also send the "toString()" message
- // of the exception. But for backward compatibility with older
- // players, we won't assume that that is there.
- String exceptionMessage;
- boolean willExceptionBeCaught = false;
- Value thrown = null;
- if (msg.getRemaining() > 0)
- {
- exceptionMessage = msg.getString();
- if (msg.getRemaining() > 0)
- {
- if (msg.getByte() != 0)
- {
- willExceptionBeCaught = (msg.getByte() != 0 ? true : false);
- msg.getPtr();
- DVariable thrownVar = extractVariable(msg);
- thrown = thrownVar.getValue();
- }
+ case DMessage.InErrorException: {
+ long offset = msg.getDWord();
+ // As of FP9, the player will also send the "toString()" message
+ // of the exception. But for backward compatibility with older
+ // players, we won't assume that that is there.
+ String exceptionMessage;
+ boolean willExceptionBeCaught = false;
+ Value thrown = null;
+ if (msg.getRemaining() > 0) {
+ exceptionMessage = msg.getString();
+ if (msg.getRemaining() > 0) {
+ if (msg.getByte() != 0) {
+ willExceptionBeCaught = (msg.getByte() != 0 ? true
+ : false);
+ msg.getPtr();
+ DVariable thrownVar = extractVariable(msg);
+ thrown = thrownVar.getValue();
}
}
- else
- {
- exceptionMessage = ""; //$NON-NLS-1$
- }
- handleFaultEvent(new ExceptionFault(exceptionMessage, willExceptionBeCaught, thrown));
- break;
+ } else {
+ exceptionMessage = ""; //$NON-NLS-1$
}
+ ExceptionFault exceptionFault = new ExceptionFault(
+ exceptionMessage, willExceptionBeCaught, thrown, msg.getTargetIsolate());
+ exceptionFault.isolateId = msg.getTargetIsolate();
+ handleFaultEvent(exceptionFault);
+ break;
+ }
- case DMessage.InErrorStackUnderflow:
- {
- long offset = msg.getDWord();
- handleFaultEvent(new StackUnderFlowFault());
- break;
- }
+ case DMessage.InErrorStackUnderflow: {
+// long offset = msg.getDWord();
+ handleFaultEvent(new StackUnderFlowFault(msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorZeroDivide:
- {
- long offset = msg.getDWord();
- handleFaultEvent(new DivideByZeroFault());
- break;
- }
+ case DMessage.InErrorZeroDivide: {
+// long offset = msg.getDWord();
+ handleFaultEvent(new DivideByZeroFault(msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorScriptStuck:
- {
- handleFaultEvent(new ScriptTimeoutFault());
- break;
- }
+ case DMessage.InErrorScriptStuck: {
+ handleFaultEvent(new ScriptTimeoutFault(msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InErrorConsole:
- {
- String s = msg.getString();
- handleFaultEvent(new ConsoleErrorFault(s));
- break;
- }
+ case DMessage.InErrorConsole: {
+ String s = msg.getString();
+ handleFaultEvent(new ConsoleErrorFault(s, msg.getTargetIsolate()));
+ break;
+ }
- case DMessage.InTrace:
- {
- String text = msg.getString();
- addEvent(new TraceEvent(text));
- break;
- }
+ case DMessage.InTrace: {
+ String text = msg.getString();
+ addEvent(new TraceEvent(text));
+ break;
+ }
- case DMessage.InSquelch:
- {
- long state = msg.getDWord();
- m_squelchEnabled = (state != 0) ? true : false;
- break;
- }
+ case DMessage.InSquelch: {
+ long state = msg.getDWord();
+ m_squelchEnabled = (state != 0) ? true : false;
+ break;
+ }
- case DMessage.InParam:
- {
- String name = msg.getString();
- String value = msg.getString();
+ case DMessage.InParam: {
+ String name = msg.getString();
+ String value = msg.getString();
- // here's where we get movie = URL and password which I'm not sure what to do with?
-// System.out.println(name+"="+value);
- m_parms.put(name, value);
+ // here's where we get movie = URL and password which I'm not sure
+ // what to do with?
+ // System.out.println(name+"="+value);
+ m_parms.put(name, value);
- // if string is a "movie", then this is a URL
- if (name.startsWith("movie")) //$NON-NLS-1$
- m_uri = convertToURI(value);
- break;
- }
+ // if string is a "movie", then this is a URL
+ if (name.startsWith("movie")) //$NON-NLS-1$
+ m_uri = convertToURI(value);
+ break;
+ }
- case DMessage.InPlaceObject:
- {
- long objId = msg.getPtr();
- String path = msg.getString();
-// m_bag.placeObject((int)objId, path);
- break;
- }
+ case DMessage.InPlaceObject: {
+ long objId = msg.getPtr();
+ String path = msg.getString();
+ // m_bag.placeObject((int)objId, path);
+ break;
+ }
- case DMessage.InSetProperty:
- {
- long objId = msg.getPtr();
- int item = msg.getWord();
- String value = msg.getString();
- break;
- }
+ case DMessage.InSetProperty: {
+ long objId = msg.getPtr();
+ int item = msg.getWord();
+ String value = msg.getString();
+ break;
+ }
- case DMessage.InNewObject:
- {
- long objId = msg.getPtr();
- break;
- }
+ case DMessage.InNewObject: {
+ long objId = msg.getPtr();
+ break;
+ }
- case DMessage.InRemoveObject:
- {
- long objId = msg.getPtr();
-// m_bag.removeObject((int)objId);
- break;
- }
+ case DMessage.InRemoveObject: {
+ long objId = msg.getPtr();
+ // m_bag.removeObject((int)objId);
+ break;
+ }
- case DMessage.InSetVariable:
- {
- long objId = msg.getPtr();
- String name = msg.getString();
- int dType = msg.getWord();
- int flags = (int) msg.getDWord();
- String value = msg.getString();
-
-// m_bag.createVariable((int)objId, name, dType, flags, value);
- break;
- }
+ case DMessage.InSetVariable: {
+ long objId = msg.getPtr();
+ String name = msg.getString();
+ int dType = msg.getWord();
+ int flags = (int) msg.getDWord();
+ String value = msg.getString();
- case DMessage.InDeleteVariable:
- {
- long objId = msg.getPtr();
- String name = msg.getString();
-// m_bag.deleteVariable((int)objId, name);
- break;
- }
+ // m_bag.createVariable((int)objId, name, dType, flags, value);
+ break;
+ }
- case DMessage.InScript:
- {
- int module = (int)msg.getDWord();
- int bitmap = (int)msg.getDWord();
- String name = msg.getString(); // in "basepath;package;filename" format
- String text = msg.getString();
- int swfIndex = -1;
-
- /* new in flash player 9: player tells us what swf this is for */
- if (msg.getRemaining() >= 4)
- swfIndex = (int)msg.getDWord();
-
- synchronized (m_source)
- {
- // create new source file
- if (putSource(swfIndex, module, bitmap, name, text))
- {
- // have we changed the list since last query
- if (!m_sourceListModified)
- addEvent(new FileListModifiedEvent());
-
- m_sourceListModified = true; /* current source list is stale */
- }
- }
- break;
+ case DMessage.InDeleteVariable: {
+ long objId = msg.getPtr();
+ String name = msg.getString();
+ // m_bag.deleteVariable((int)objId, name);
+ break;
+ }
+
+ case DMessage.InScript: {
+ int module = (int) msg.getDWord();
+ int bitmap = (int) msg.getDWord();
+ String name = msg.getString(); // in "basepath;package;filename"
+ // format
+ String text = msg.getString();
+ int swfIndex = -1;
+ int isolateIndex = -1;
+
+ /* new in flash player 9: player tells us what swf this is for */
+ if (msg.getRemaining() >= 4)
+ swfIndex = (int) msg.getDWord();
+
+ isolateIndex = msg.getTargetIsolate();
+ getOrCreateIsolate(isolateIndex);
+ if (putSource(swfIndex, module, bitmap, name, text,
+ isolateIndex)) {
+ // have we changed the list since last query
+ if (!m_sourceListModified)
+ addEvent(new FileListModifiedEvent());
+
+ m_sourceListModified = true;
}
+ break;
+ }
- case DMessage.InRemoveScript:
- {
- long module = msg.getDWord();
- synchronized (m_source)
- {
- if (removeSource((int)module))
- {
- // have we changed the list since last query
- if (!m_sourceListModified)
- addEvent(new FileListModifiedEvent());
-
- m_sourceListModified = true; /* current source list is stale */
- }
+ case DMessage.InRemoveScript: {
+ long module = msg.getDWord();
+ int isolateId = msg.getTargetIsolate();
+ Map<Integer, DModule> source = getIsolateState(isolateId).m_source;
+ synchronized (source) {
+ if (removeSource((int) module, isolateId)) {
+ // have we changed the list since last query
+ if (!m_sourceListModified)
+ addEvent(new FileListModifiedEvent());
+
+ m_sourceListModified = true; /* current source list is stale */
}
- break;
}
+ break;
+ }
- case DMessage.InAskBreakpoints:
- {
- // the player has just loaded a swf and we know the player
- // has halted, waiting for us to continue. The only caveat
- // is that it looks like it still does a number of things in
- // the background which take a few seconds to complete.
- if (m_suspendInfo == null)
- m_suspendInfo = new DSuspendInfo(SuspendReason.ScriptLoaded, 0, 0, 0, 0);
- break;
+ case DMessage.InAskBreakpoints: {
+ // the player has just loaded a swf and we know the player
+ // has halted, waiting for us to continue. The only caveat
+ // is that it looks like it still does a number of things in
+ // the background which take a few seconds to complete.
+ int targetIsolate = msg.getTargetIsolate();
+ DSuspendInfo iSusInfo = getIsolateState(targetIsolate).m_suspendInfo;
+ if (iSusInfo == null) {
+ iSusInfo = new DSuspendInfo(SuspendReason.ScriptLoaded, 0,
+ 0, 0, 0);
}
+ break;
+ }
- case DMessage.InBreakAt:
- {
- long bp = msg.getDWord();
- long id = msg.getPtr();
- String stack = msg.getString();
-// System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16)+",id="+id+",stack=\n"+stack);
-
- //System.out.println("InBreakAt");
-
- int module = DLocation.decodeFile(bp);
- int line = DLocation.decodeLine (bp);
- addEvent(new BreakEvent(module, line));
- break;
+ case DMessage.InBreakAt: {
+ long bp = 0, wideLine = 0, wideModule = 0;
+ if (!m_wideLines) {
+ bp = msg.getDWord();
}
-
- case DMessage.InContinue:
- {
- /* we are running again so trash all our variable contents */
- continuing();
- break;
+ else {
+ wideModule = msg.getDWord();
+ wideLine = msg.getDWord();
}
-
- case DMessage.InSetLocalVariables:
- {
- long objId = msg.getPtr();
-// m_bag.markObjectLocal((int)objId, true);
- break;
+ long id = msg.getPtr();
+ String stack = msg.getString();
+ int targetIsolate = msg.getTargetIsolate();
+
+ int module = DLocation.decodeFile(bp);
+ int line = DLocation.decodeLine(bp);
+ if (m_wideLines) {
+ module = (int)wideModule;
+ line = (int)wideLine;
}
+ addEvent(new BreakEvent(module, line, targetIsolate));
+ break;
+ }
- case DMessage.InSetBreakpoint:
- {
- long count = msg.getDWord();
- while(count-- > 0)
- {
- long bp = msg.getDWord();
+ case DMessage.InContinue: {
+ /* we are running again so trash all our variable contents */
+ continuing(msg.getTargetIsolate());
+ break;
+ }
- int fileId = DLocation.decodeFile(bp);
- int line = DLocation.decodeLine(bp);
+ case DMessage.InSetLocalVariables: {
+// long objId = msg.getPtr();
+ // m_bag.markObjectLocal((int)objId, true);
+ break;
+ }
- DModule file = getSource(fileId);
- DLocation l = new DLocation(file, line);
+ case DMessage.InSetBreakpoint: {
+ long count = msg.getDWord();
+ int targetIsolate = msg.getTargetIsolate();
+ while (count-- > 0) {
+ long bp = 0, moduleNumber = 0, lineNumber = 0;
+ if (!m_wideLines) {
+ bp = msg.getDWord();
+ }
+ else {
+ moduleNumber = msg.getDWord();
+ lineNumber = msg.getDWord();
+ }
- if (file != null)
- addBreakpoint((int)bp, l);
+ int fileId = DLocation.decodeFile(bp);
+ int line = DLocation.decodeLine(bp);
+ if (m_wideLines) {
+ fileId = (int)moduleNumber;
+ line = (int)lineNumber;
}
- break;
- }
- case DMessage.InNumScript:
- {
- /* lets us know how many scripts there are */
- int num = (int)msg.getDWord();
- DSwfInfo swf;
+ DModule file = null;
+ file = getSource(fileId, targetIsolate);
- /*
- * New as of flash player 9: another dword indicating which swf this is for.
- * That means we don't have to guess whether this is for an old SWF
- * which has just had some more modules loaded, or for a new SWF!
- */
- if (msg.getRemaining() >= 4)
- {
- int swfIndex = (int) msg.getDWord();
- swf = getOrCreateSwfInfo(swfIndex);
- m_lastSwfInfo = swf;
- }
- else
- {
- /* This is not flash player 9 (or it is an early build of fp9).
- *
- * We use this message as a trigger that a new swf has been loaded, so make sure
- * we are ready to accept the scripts.
- */
- swf = getActiveSwfInfo();
+ DLocation l = new DLocation(file, line, targetIsolate);
+
+ if (file != null) {
+ addBreakpoint((int) bp, l, targetIsolate);
}
+ }
+ break;
+ }
- // It is NOT an error for the player to have sent us a new,
- // different sourceExpectedCount from whatever we had before!
- // In fact, this happens all the time, whenever a SWF has more
- // than one ABC.
- swf.setSourceExpectedCount(num);
- break;
+ case DMessage.InNumScript: {
+ /* lets us know how many scripts there are */
+ int num = (int) msg.getDWord();
+ int targetIsolate = msg.getTargetIsolate();
+ DSwfInfo swf;
+
+ /*
+ * New as of flash player 9: another dword indicating which swf this
+ * is for. That means we don't have to guess whether this is for an
+ * old SWF which has just had some more modules loaded, or for a new
+ * SWF!
+ */
+ if (msg.getRemaining() >= 4) {
+ int swfIndex = (int) msg.getDWord();
+ swf = getOrCreateSwfInfo(swfIndex, targetIsolate);
+ getIsolateState(targetIsolate).m_lastSwfInfo = swf;
+ } else {
+ /*
+ * This is not flash player 9 (or it is an early build of fp9).
+ *
+ * We use this message as a trigger that a new swf has been
+ * loaded, so make sure we are ready to accept the scripts.
+ */
+ swf = getActiveSwfInfo(targetIsolate);
}
- case DMessage.InRemoveBreakpoint:
- {
- long count = msg.getDWord();
- while(count-- > 0)
- {
- long bp = msg.getDWord();
- removeBreakpoint((int)bp);
- }
- break;
+ // It is NOT an error for the player to have sent us a new,
+ // different sourceExpectedCount from whatever we had before!
+ // In fact, this happens all the time, whenever a SWF has more
+ // than one ABC.
+ swf.setSourceExpectedCount(num);
+ break;
+ }
+ case DMessage.InRemoveBreakpoint: {
+ long count = msg.getDWord();
+ int isolateId = msg.getTargetIsolate();
+ while (count-- > 0) {
+ long bp = msg.getDWord();
+ removeBreakpoint((int) bp, isolateId);
}
+ break;
- case DMessage.InBreakAtExt:
- {
- long bp = msg.getDWord();
- long num = msg.getDWord();
-
-// System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16));
- /* we have stack info to store away */
- clearFrames(); // just in case
- int depth = 0;
- while(num-- > 0)
- {
- long bpi = msg.getDWord();
- long id = msg.getPtr();
- String stack = msg.getString();
- int module = DLocation.decodeFile(bpi);
- int line = DLocation.decodeLine (bpi);
- DModule m = getSource(module);
- DStackContext c = new DStackContext( module, line, m, id, stack, depth);
- // If addFrame() returns false, that means it chose to ignore this
- // frame, so we do NOT want to increment our depth for the next
- // time through the loop. If it returns true, then we do want to.
- if (addFrame(c))
- ++depth;
-// System.out.println(" this="+id+",@"+(bpi&0xffff)+":"+(bpi>>16)+",stack="+stack);
- }
- mapOldFramesToNew();
- break;
+ }
+ case DMessage.InBreakAtExt: {
+ long bp = 0, wideLine = 0, wideModule = 0;
+ if (!m_wideLines) {
+ bp = msg.getDWord();
}
-
- case DMessage.InFrame:
- {
- // For InFrame the first element is really our frame id
- DValue frame = null;
- DVariable child = null;
- ArrayList<DVariable> v = new ArrayList<DVariable>();
- ArrayList<DVariable> registers = new ArrayList<DVariable>();
-
- int depth = (int)msg.getDWord(); // depth of frame
-
- // make sure we have a valid depth
- if (depth > -1)
- {
- // first thing is number of registers
- int num = (int)msg.getDWord();
- for(int i=0; i<num; i++)
- registers.add( extractRegister(msg, i+1) );
+ else {
+ wideModule = msg.getDWord();
+ wideLine = msg.getDWord();
+ }
+ long num = msg.getDWord();
+
+ int targetIsolate = msg.getTargetIsolate();
+ // System.out.println(msg.getInTypeName()+",bp="+(bp&0xffff)+":"+(bp>>16));
+ /* we have stack info to store away */
+ clearFrames(targetIsolate); // just in case
+ int depth = 0;
+
+ while (num-- > 0) {
+ long bpi = 0, wideLinei= 0, wideModulei = 0;
+ if (!m_wideLines) {
+ bpi = msg.getDWord();
+ }
+ else {
+ wideModulei = msg.getDWord();
+ wideLinei = msg.getDWord();
}
+ long id = msg.getPtr();
+ String stack = msg.getString();
+ int module = DLocation.decodeFile(bpi);
+ int line = DLocation.decodeLine(bpi);
+ if (m_wideLines) {
+ module = (int)wideModulei;
+ line = (int)wideLinei;
+ }
+ DModule m = null;
+ m = getSource(module, targetIsolate);
+ DStackContext c = new DStackContext(module, line, m, id, stack,
+ depth, targetIsolate);
+ // If addFrame() returns false, that means it chose to ignore
+ // this
+ // frame, so we do NOT want to increment our depth for the next
+ // time through the loop. If it returns true, then we do want
+ // to.
+ if (addFrame(c, targetIsolate))
+ ++depth;
+ // System.out.println(" this="+id+",@"+(bpi&0xffff)+":"+(bpi>>16)+",stack="+stack);
+ }
+ mapOldFramesToNew(targetIsolate);
+ if (targetIsolate != Isolate.DEFAULT_ID) {
+ // ask for isolate id if it is present
+ appendIsolateInfoToFrame(targetIsolate);
- int currentArg = -1;
- boolean gettingScopeChain = false;
+ }
+ break;
+
+ }
- // then our frame itself
- while(msg.getRemaining() > 0)
- {
- long frameId = msg.getPtr();
+ case DMessage.InFrame: {
+ // For InFrame the first element is really our frame id
+ DValue frame = null;
+ DVariable child = null;
+ ArrayList<DVariable> v = new ArrayList<DVariable>();
+ ArrayList<DVariable> registers = new ArrayList<DVariable>();
+ int targetIsolate = msg.getTargetIsolate();
+ int depth = (int) msg.getDWord(); // depth of frame
+
+ // make sure we have a valid depth
+ if (depth > -1) {
+ // first thing is number of registers
+ int num = (int) msg.getDWord();
+ for (int i = 0; i < num; i++)
+ registers.add(extractRegister(msg, i + 1));
+ }
- if (frame == null)
- {
- frame = getOrCreateValue(frameId);
- extractVariable(msg); // put the rest of the info in the trash
+ int currentArg = -1;
+ boolean gettingScopeChain = false;
+
+ // then our frame itself
+ while (msg.getRemaining() > 0) {
+ long frameId = msg.getPtr();
+
+ if (frame == null) {
+ frame = getOrCreateValue(frameId, targetIsolate);
+ extractVariable(msg); // put the rest of the info in the
+ // trash
+ } else {
+ child = extractVariable(msg);
+ if (currentArg == -1
+ && child.getName().equals(ARGUMENTS_MARKER)) {
+ currentArg = 0;
+ gettingScopeChain = false;
+ } else if (child.getName().equals(SCOPE_CHAIN_MARKER)) {
+ currentArg = -1;
+ gettingScopeChain = true;
+ } else if (currentArg >= 0) {
+ // work around a compiler bug: If the variable's name is
+ // "undefined",
+ // then change its name to "_argN", where "N" is the
+ // argument index,
+ // e.g. _arg1, _arg2, etc.
+ ++currentArg;
+ if (child.getName().equals("undefined")) //$NON-NLS-1$
+ child.setName("_arg" + currentArg); //$NON-NLS-1$
}
- else
- {
- child = extractVariable(msg);
- if (currentArg == -1 && child.getName().equals(ARGUMENTS_MARKER))
- {
- currentArg = 0;
- gettingScopeChain = false;
- }
- else if (child.getName().equals(SCOPE_CHAIN_MARKER))
- {
- currentArg = -1;
- gettingScopeChain = true;
- }
- else if (currentArg >= 0)
- {
- // work around a compiler bug: If the variable's name is "undefined",
- // then change its name to "_argN", where "N" is the argument index,
- // e.g. _arg1, _arg2, etc.
- ++currentArg;
- if (child.getName().equals("undefined")) //$NON-NLS-1$
- child.setName("_arg" + currentArg); //$NON-NLS-1$
- }
- // All args and locals get added as "children" of
- // the frame; but scope chain entries do not.
- if (!gettingScopeChain)
- addVariableMember(frameId, child);
+ // All args and locals get added as "children" of
+ // the frame; but scope chain entries do not.
+ if (!gettingScopeChain)
+ addVariableMember(frameId, child, targetIsolate);
- // Everything gets added to the ordered list of
- // variables that came in.
- v.add(child);
- }
+ // Everything gets added to the ordered list of
+ // variables that came in.
+ v.add(child);
}
+ }
- // let's transfer our newly gained knowledge into the stack context
- if (depth == 0)
- populateRootNode(frame, v);
- else
- populateFrame(depth, v);
+ // let's transfer our newly gained knowledge into the stack context
+ if (depth == 0)
+ populateRootNode(frame, v, targetIsolate);
+ else
+ populateFrame(depth, v, targetIsolate);
- break;
- }
+ break;
+ }
- case DMessage.InOption:
- {
- String s = msg.getString();
- String v = msg.getString();
- m_options.put(s, v);
- break;
- }
+ case DMessage.InOption: {
+ String s = msg.getString();
+ String v = msg.getString();
+ m_options.put(s, v);
+ break;
+ }
- case DMessage.InGetVariable:
- {
- // For InGetVariable the first element is the original entity we requested
- DValue parent = null;
- DVariable child = null;
- String definingClass = null;
- int level = 0;
- int highestLevelWithMembers = -1;
- List<String> classes = new ArrayList<String>();
-
- while(msg.getRemaining() > 0)
- {
- long parentId = msg.getPtr();
-
- // build or get parent node
- if (parent == null)
- {
- String name = msg.getString();
-
- // pull the contents of the node which normally are disposed of except if we did a 0,name call
- m_lastInGetVariable = extractVariable(msg, name);
-
- parent = getOrCreateValue(parentId);
- }
- else
- {
- // extract the child and add it to the parent.
- child = extractVariable(msg);
- if (showMember(child)) {
- if (child.isAttributeSet(VariableAttribute.IS_DYNAMIC)) {
- // Dynamic attributes always come in marked as a member of
- // class "Object"; but to the user, it makes more sense to
- // consider them as members of the topmost class.
- if (classes.size() > 0) {
- child.setDefiningClass(0, classes.get(0));
- highestLevelWithMembers = Math.max(highestLevelWithMembers, 0);
- }
- } else {
- child.setDefiningClass(level, definingClass);
- if (definingClass != null) {
- highestLevelWithMembers = Math.max(highestLevelWithMembers, level);
- }
+ case DMessage.InGetVariable: {
+ // For InGetVariable the first element is the original entity we
+ // requested
+ DValue parent = null;
+ DVariable child = null;
+ String definingClass = null;
+ int level = 0;
+ int targetIsolate = msg.getTargetIsolate();
+ int highestLevelWithMembers = -1;
+ List<String> classes = new ArrayList<String>();
+
+ while (msg.getRemaining() > 0) {
+ long parentId = msg.getPtr();
+
+ // build or get parent node
+ if (parent == null) {
+ String name = msg.getString();
+
+ // pull the contents of the node which normally are disposed
+ // of except if we did a 0,name call
+ getIsolateState(targetIsolate).m_lastInGetVariable = extractVariable(msg, name);
+
+ parent = getOrCreateValue(parentId, targetIsolate);
+ } else {
+ // extract the child and add it to the parent.
+ child = extractVariable(msg);
+ if (showMember(child)) {
+ if (child.isAttributeSet(VariableAttribute.IS_DYNAMIC)) {
+ // Dynamic attributes always come in marked as a
+ // member of
+ // class "Object"; but to the user, it makes more
+ // sense to
+ // consider them as members of the topmost class.
+ if (classes.size() > 0) {
+ child.setDefiningClass(0, classes.get(0));
+ highestLevelWithMembers = Math.max(
+ highestLevelWithMembers, 0);
}
- addVariableMember(parent.getId(), child);
} else {
- if (isTraits(child)) {
- definingClass = child.getQualifiedName();
- level = classes.size();
-
- // If the traits name end with "$", then it represents a class object --
- // in other words, the variables inside it are static variables of that
- // class. In that case, we need to juggle the information. For example,
- // if we are told that a variable is a member of "MyClass$", we actually
- // store it into the information for "MyClass".
- if (definingClass.endsWith("$")) { //$NON-NLS-1$
- String classWithoutDollar = definingClass.substring(0, definingClass.length() - 1);
- int indexOfClass = classes.indexOf(classWithoutDollar);
- if (indexOfClass != -1) {
- level = indexOfClass;
- definingClass = classWithoutDollar;
- }
+ child.setDefiningClass(level, definingClass);
+ if (definingClass != null) {
+ highestLevelWithMembers = Math.max(
+ highestLevelWithMembers, level);
+ }
+ }
+ addVariableMember(parent.getId(), child, targetIsolate);
+ } else {
+ if (isTraits(child)) {
+ definingClass = child.getQualifiedName();
+ level = classes.size();
+
+ // If the traits name end with "$", then it
+ // represents a class object --
+ // in other words, the variables inside it are
+ // static variables of that
+ // class. In that case, we need to juggle the
+ // information. For example,
+ // if we are told that a variable is a member of
+ // "MyClass$", we actually
+ // store it into the information for "MyClass".
+ if (definingClass.endsWith("$")) { //$NON-NLS-1$
+ String classWithoutDollar = definingClass
+ .substring(0,
+ definingClass.length() - 1);
+ int indexOfClass = classes
+ .indexOf(classWithoutDollar);
+ if (indexOfClass != -1) {
+ level = indexOfClass;
+ definingClass = classWithoutDollar;
}
+ }
- // It wasn't static -- so, add this class to the end of the list of classes
- if (level == classes.size()) {
- classes.add(definingClass);
- }
+ // It wasn't static -- so, add this class to the end
+ // of the list of classes
+ if (level == classes.size()) {
+ classes.add(definingClass);
}
}
}
}
+ }
- if (parent != null && parent.getClassHierarchy(true) == null) {
- parent.setClassHierarchy(classes.toArray(new String[classes.size()]), highestLevelWithMembers+1);
- }
-
- break;
+ if (parent != null && parent.getClassHierarchy(true) == null) {
+ parent.setClassHierarchy(
+ classes.toArray(new String[classes.size()]),
+ highestLevelWithMembers + 1);
}
- case DMessage.InWatch: // for AS2; sends 16-bit ID field
- case DMessage.InWatch2: // for AS3; sends 32-bit ID field
- {
- // This message is sent whenever a watchpoint is added
- // modified or removed.
- //
- // For an addition, flags will be non-zero and
- // success will be true.
- //
- // For a modification flags will be non-zero.
- // and oldFlags will be non-zero and success
- // will be true. Additionally oldFlags will not
- // be equal to flags.
- //
- // For a removal flags will be zero. oldFlags
- // will be non-zero.
- //
- // flags identifies the type of watchpoint added,
- // see WatchKind.
- //
- // success indicates whether the operation was successful
- //
- // request. It will be associated with the watchpoint.
- int success = msg.getWord();
- int oldFlags = msg.getWord();
- int oldTag = msg.getWord();
- int flags = msg.getWord();
- int tag = msg.getWord();
- // for AS2, the ID came in above as a Word. For AS3, the above value is
- // bogus, and it has been sent again as a DWord.
- long id = ((type == DMessage.InWatch2) ? msg.getPtr() : msg.getWord());
- String name = msg.getString();
-
- if (success != 0)
- {
- if (flags == 0)
- {
- removeWatchpoint(oldTag);
- }
- else
- {
- // modification or addition is the same to us
- // a new watch is created and added into the table
- // while any old entry if it exists is removed.
- removeWatchpoint(oldTag);
- DWatch w = new DWatch(id, name, flags, tag);
- addWatchpoint(w);
- }
+ break;
+ }
+
+ case DMessage.InWatch: // for AS2; sends 16-bit ID field
+ case DMessage.InWatch2: // for AS3; sends 32-bit ID field
+ {
+ // This message is sent whenever a watchpoint is added
+ // modified or removed.
+ //
+ // For an addition, flags will be non-zero and
+ // success will be true.
+ //
+ // For a modification flags will be non-zero.
+ // and oldFlags will be non-zero and success
+ // will be true. Additionally oldFlags will not
+ // be equal to flags.
+ //
+ // For a removal flags will be zero. oldFlags
+ // will be non-zero.
+ //
+ // flags identifies the type of watchpoint added,
+ // see WatchKind.
+ //
+ // success indicates whether the operation was successful
+ //
+ // request. It will be associated with the watchpoint.
+ int success = msg.getWord();
+ int oldFlags = msg.getWord();
+ int oldTag = msg.getWord();
+ int flags = msg.getWord();
+ int tag = msg.getWord();
+ // for AS2, the ID came in above as a Word. For AS3, the above value
+ // is
+ // bogus, and it has been sent again as a DWord.
+ long id = ((type == DMessage.InWatch2) ? msg.getPtr() : msg
+ .getWord());
+ String name = msg.getString();
+ int targetIsolate = msg.getTargetIsolate();
+
+ if (success != 0) {
+ if (flags == 0) {
+ removeWatchpoint(oldTag, targetIsolate);
+ } else {
+ // modification or addition is the same to us
+ // a new watch is created and added into the table
+ // while any old entry if it exists is removed.
+ removeWatchpoint(oldTag, targetIsolate);
+ DWatch w = new DWatch(id, name, flags, tag, targetIsolate);
+ addWatchpoint(w, targetIsolate);
}
- break;
}
+ break;
+ }
- case DMessage.InGetSwf:
- {
- // we only house the swf temporarily, PlayerSession then
- // pieces it back into swfinfo record. Also, we don't
- // send any extra data in the message so that we need not
- // copy the bytes.
- m_swf = msg.getData();
- break;
- }
-
- case DMessage.InGetSwd:
- {
- // we only house the swd temporarily, PlayerSession then
- // pieces it back into swfinfo record.
- m_swd = msg.getData();
- break;
- }
-
- case DMessage.InBreakReason:
- {
- // the id map 1-1 with out SuspendReason interface constants
- int suspendReason = msg.getWord();
- int suspendPlayer = msg.getWord(); // item index of player
- int breakOffset = (int)msg.getDWord(); // current script offset
- int prevBreakOffset = (int)msg.getDWord(); // prev script offset
- int nextBreakOffset = (int)msg.getDWord(); // next script offset
- m_suspendInfo = new DSuspendInfo(suspendReason, suspendPlayer, breakOffset, prevBreakOffset, nextBreakOffset);
-
- // augment the current frame with this information. It
- // should work ok since we only get this message after a
- // InBreakAtExt message
- try
- {
- DStackContext c = getFrame(0);
- c.setOffset(breakOffset);
- c.setSwfIndex(suspendPlayer);
- }
- catch(Exception e)
- {
- if (Trace.error)
- {
- Trace.trace("Oh my god, gag me with a spoon...getFrame(0) call failed"); //$NON-NLS-1$
- e.printStackTrace();
- }
- }
- break;
- }
+ case DMessage.InGetSwf: {
+ // we only house the swf temporarily, PlayerSession then
+ // pieces it back into swfinfo record. Also, we don't
+ // send any extra data in the message so that we need not
+ // copy the bytes.
+ m_swf = msg.getData();
+ break;
+ }
- // obtain raw action script byte codes
- case DMessage.InGetActions:
- {
- int item = msg.getWord();
- int rsvd = msg.getWord();
- int at = (int)msg.getDWord();
- int len = (int)msg.getDWord();
- int i = 0;
+ case DMessage.InGetSwd: {
+ // we only house the swd temporarily, PlayerSession then
+ // pieces it back into swfinfo record.
+ m_swd = msg.getData();
+ break;
+ }
- m_actions = (len <= 0) ? null : new byte[len];
- while(len-- > 0)
- m_actions[i++] = (byte)msg.getByte();
+ case DMessage.InBreakReason: {
+ // the id map 1-1 with out SuspendReason interface constants
+ int suspendReason = msg.getWord();
+ int suspendPlayer = msg.getWord(); // item index of player
+ int breakOffset = (int) msg.getDWord(); // current script offset
+ int prevBreakOffset = (int) msg.getDWord(); // prev script offset
+ int nextBreakOffset = (int) msg.getDWord(); // next script offset
+ int targetIsolate = msg.getTargetIsolate();
+
+ getIsolateState(targetIsolate).m_suspendInfo = new DSuspendInfo(
+ suspendReason, suspendPlayer, breakOffset,
+ prevBreakOffset, nextBreakOffset);
+
+ // augment the current frame with this information. It
+ // should work ok since we only get this message after a
+ // InBreakAtExt message
+ try {
+ DSt
<TRUNCATED>