package org.eclipse.dltk.internal.debug.core.model; import org.eclipse.dltk.dbgp.IDbgpStackLevel; import org.eclipse.dltk.dbgp.exceptions.DbgpException; import org.eclipse.dltk.debug.core.DLTKDebugPlugin; import org.eclipse.dltk.debug.core.model.IScriptStack; import org.eclipse.dltk.debug.core.model.IScriptStackFrame; public class ScriptStack implements IScriptStack { public static final IScriptStackFrame[] NO_STACK_FRAMES = new IScriptStackFrame[0]; private IScriptStackFrame[] frames; private final Object framesLock = new Object(); private final ScriptThread thread; public ScriptStack(ScriptThread thread) { this.thread = thread; this.frames = NO_STACK_FRAMES; } public void update(boolean logErrors) { try { readFrames(); } catch (DbgpException e) { if (logErrors) { DLTKDebugPlugin.log(e); } } } protected IDbgpStackLevel[] requrestStackLevels() throws DbgpException { return thread.getDbgpSession().getCoreCommands().getStackLevels(); } protected void readFrames() throws DbgpException { final IDbgpStackLevel[] levels = requrestStackLevels(); ((ScriptDebugTarget) thread.getScriptDebugTarget()) .updateStackLevels(levels); synchronized (framesLock) { final int newSize = levels.length; final int oldSize = frames.length; final int numToRebind = Math.min(newSize, oldSize); final ScriptStackFrame[] newFrames = new ScriptStackFrame[newSize]; for (int depth = 0; depth < numToRebind; ++depth) { final ScriptStackFrame oldFrame = (ScriptStackFrame) frames[oldSize - depth - 1]; newFrames[newSize - depth - 1] = oldFrame .bind(levels[newSize - depth - 1]); } final int newCount = newSize - oldSize; for (int i = 0; i < newCount; ++i) { newFrames[i] = new ScriptStackFrame(this, levels[i]); } frames = newFrames; } } @Override public ScriptThread getThread() { return thread; } @Override public int size() { synchronized (framesLock) { return frames.length; } } @Override public boolean hasFrames() { synchronized (framesLock) { return frames.length > 0; } } @Override public IScriptStackFrame[] getFrames() { synchronized (framesLock) { return frames; } } @Override public IScriptStackFrame getTopFrame() { synchronized (framesLock) { return frames.length > 0 ? frames[0] : null; } } public void updateFrames() { synchronized (framesLock) { for (int i = 0; i < frames.length; i++) { ((ScriptStackFrame) frames[i]).updateVariables(); } } } /** * @return */ public boolean isInitialized() { synchronized (framesLock) { return frames != NO_STACK_FRAMES; } } }