blob: 855082e62267ff597c0131c918d91b9dbc77d5f7 [file] [log] [blame]
/*
* 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.
*/
package flash.tools.debugger.concrete;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import flash.tools.debugger.Frame;
import flash.tools.debugger.Location;
import flash.tools.debugger.NoResponseException;
import flash.tools.debugger.NotConnectedException;
import flash.tools.debugger.NotSuspendedException;
import flash.tools.debugger.Session;
import flash.tools.debugger.Variable;
public class DStackContext implements Frame
{
private DModule m_source;
private String m_functionSignature;
private int m_depth;
private int m_module;
private int m_line;
private DVariable m_this;
private Map<String, DVariable> m_args;
private Map<String, DVariable> m_locals;
private List<DVariable> m_scopeChain;
private DLocation m_location;
private int m_swfIndex; /* index of swf that we halted within (really part of location) */
private int m_offset; /* offset within swf where we halted. (really part of location) */
private boolean m_populated;
private DVariable m_activationObject;
private int m_isolateId;
public DStackContext(int module, int line, DModule f, long thisId /* bogus */,
String functionSignature, int depth, int isolateId)
{
m_source = f;
m_module = module;
m_line = line;
// the passed-in 'thisId' seems to always be equal to one, which does more harm than good
m_this = null;
m_functionSignature = functionSignature;
m_depth = depth;
m_args = new LinkedHashMap<String, DVariable>(); // preserves order
m_locals = new LinkedHashMap<String, DVariable>(); // preserves order
m_scopeChain = new ArrayList<DVariable>();
m_populated = false;
m_isolateId = isolateId;
m_location = new DLocation(m_source, line, isolateId);
}
/*
* @see flash.tools.debugger.Frame#getLocation()
*/
public Location getLocation()
{
return m_location;
}
/*
* @see flash.tools.debugger.Frame#getArguments(flash.tools.debugger.Session)
*/
public Variable[] getArguments(Session s) throws NoResponseException, NotSuspendedException, NotConnectedException
{
populate(s);
return m_args.values().toArray( new Variable[m_args.size()] );
}
/*
* @see flash.tools.debugger.Frame#getLocals(flash.tools.debugger.Session)
*/
public Variable[] getLocals(Session s) throws NoResponseException, NotSuspendedException, NotConnectedException
{
populate(s);
return m_locals.values().toArray( new Variable[m_locals.size()] );
}
/*
* @see flash.tools.debugger.Frame#getThis(flash.tools.debugger.Session)
*/
public Variable getThis(Session s) throws NoResponseException, NotSuspendedException, NotConnectedException
{
populate(s);
return getThis();
}
/*
* @see flash.tools.debugger.Frame#getScopeChain()
*/
public Variable[] getScopeChain(Session s) throws NoResponseException, NotSuspendedException, NotConnectedException
{
populate(s);
return m_scopeChain.toArray(new Variable[m_scopeChain.size()]);
}
/* getters */
public String getCallSignature() { return m_functionSignature; }
public int getModule() { return m_module; }
public int getLine() { return m_line; }
public DVariable getThis() { return m_this; }
/* setters */
void addArgument(DVariable v) { m_args.put(v.getName(), v); }
void addLocal(DVariable v) { m_locals.put(v.getName(), v); }
void addScopeChainEntry(DVariable v) { m_scopeChain.add(v); }
void removeAllArguments() { m_args.clear(); }
void removeAllLocals() { m_locals.clear(); m_activationObject = null; }
void removeAllScopeChainEntries() { m_scopeChain.clear(); }
void removeAllVariables() { removeAllLocals(); removeAllArguments(); removeAllScopeChainEntries(); }
void setDepth(int depth) { m_depth = depth; }
void setThis(DVariable v) { m_this = v; }
void setSwfIndex(int index) { m_swfIndex = index; }
void setOffset(int offset) { m_offset = offset; }
void setIsolateId(int id) { m_isolateId = id; }
void markStale() { m_populated = false; } // triggers a reload of variables.
/**
* Removes the specified variable from the list of locals, and
* remembers that the specified variable is the "activation object"
* for this frame. See bug 155031.
*/
void convertLocalToActivationObject(DVariable v)
{
m_activationObject = v;
m_locals.remove(v.getName());
}
/**
* Gets the activation object for this frame, or <code>null</code>
* if none. See bug FB-2674.
*/
DVariable getActivationObject()
{
return m_activationObject;
}
/**
* Populate ensures that we have some locals and args. That is
* that we have triggered a InFrame call to the player
* @throws NoResponseException
* @throws NotSuspendedException
* @throws NotConnectedException
*/
void populate(Session s) throws NoResponseException, NotSuspendedException, NotConnectedException
{
if (!m_populated)
{
PlayerSession ses = ((PlayerSession)s);
ses.requestFrame(m_depth, m_isolateId);
m_populated = true;
}
}
public int getIsolateId()
{
return m_isolateId;
}
}